I have an android application with different flavours.What I mean by flavours is that they differ only in their application name,icon and a url that webview in the application uses.
What I have now:
Application 1 with app_name1 and icon1:
{
Code...
myWebview.loadUrl(url1);
code..
}
Application 2 with app_name2 and icon2:
{
SameCode...
myWebview.loadUrl(url2)
Samecode..
}
What I would like to have :
Application(pick the application name and icon from build parameter):
{
Code ..
myWebview.loadUrl(pick the url from build parameter)
Code..
}
Is this possible?
This would be so good to have as I am manually copying any change that i do in either of the projects to the other and I am scared about how I would handle more than 2 "flavours".
You probably want to take a look at Library Projects. See for instance this blog post:
Library Projects allow you to share some whole parts of your applications, resources included.
The main and immediate use is to create several versions of the same application.
You should in any case be using resources to refer to these things. So e.g
<application android:label="#string:app_name" android:icon="#drawable:icon">
in your AndroidManifest.xml, and
String rl = getString(R.string.url);
in your code.
Then you simply have to swap in the right res/values/strings.xml and res/drawable/icon.png, and change the name of your final apk.
Related
I have a Flutter app having size around 850 MB (AAB). Most of these 850MB are assets- video files (750 MB).
The solution to publish it in the Google Play Store is to use deferred components (or to use private server to download video files after installation- I don't want to do this at this stage).
The problem is I found very little information about it.
Here: https://docs.flutter.dev/perf/deferred-components,
and here: https://github.com/flutter/flutter/wiki/Deferred-Components.
And few questions on stackoverflow, most unanswered.
So, my questions:
1. If I understand correctly, each component must be less than 150 MB?
As I wrote, the video files are 750 MB and there are 1150 of them.
So, I need to create 5 or 6 components?
Now my pubspec.yaml looks like:
pubspec.yaml
assets:
- assets/
- assets/db/
- assets/media/
- assets/media/video/
- assets/pics/
- assets/pics/avatars/
So, I should remove this line:
- assets/media/video/
and add:
flutter:
...
deferred-components:
- name: videoComponent1
libraries:
- package:MyAppName/video1.dart
assets:
- assets/media/video/video1.mp4
- assets/media/video/video2.mp4
...
- assets/media/video/video100.mp4
...
- name: videoComponent5
libraries:
- package:MyAppName/video5.dart
assets:
- assets/media/video/video1000.mp4
- assets/media/video/video1001.mp4
...
- assets/media/video/video1150.mp4
This method is a bit time consuming. I know I can use wildcard directories:
assets:
- assets/media/video/video1/
But then I have to handle it in my video player widget (i am using video_player plugin). I can put files in alphabetical order. For example, I will put video files with a name starting with letter "A" in a video1 package, "B" in a video2 etc. And then:
if(fileName.substring(0,1)=='a') {
filePath = 'assets/media/video/video1/$fileName';
} else if...
But this is also a tedious method.
Any other ideas? (I can't rename files in the database- it's an official external source, files and base are updated from time to time).
2. There are assets-only components. They can be defined by omitting the "libraries" section. It's clear. But how to use these components?
Documentation says: These assets-only components must be installed with the DeferredComponent utility class in services rather than loadLibrary(). There is also loadLibrary method. How to use it all together?
Something like this?
import 'package:flutter/services.dart';
var component = DeferredComponent.installDeferredComponent(componentName : video1);
How to show users the component download process is still in progress?
Assets-only components documentation is a bit lacking (in my opinion). I assume that the first step of the documentation is necessary. But what does step two look like?
What would i like to achieve?
Download all video files during the first app run (e.g on the onboarding screen) and use them in all my widgets in the same way as any other local asset.
(that's exactly what is in the installDeferredComponent method documentation: Assets installed by this method may be accessed in the same way as any other local asset by providing a string path to the asset).
Results (added 06.03.22)
I did everything in accordance with the documentation, I generated an aab file without errors.
I used the installDeferredComponent method as follows:
loadDeferredComponents() async {
await DeferredComponent.installDeferredComponent(
componentName: 'videoComponent1');
await DeferredComponent.installDeferredComponent(
componentName: 'videoComponent2');
await DeferredComponent.installDeferredComponent(
componentName: 'videoComponent3');
...
}
The aab file looks OK:
But when i try to upload it to Google Play i keep getting the message: One or more of the auto-generated multi-APKs exceeds the maximum allowed size of 150 MB.
I think I will give up the deferred components. I don't really know what I'm doing wrong.
Yep I had exact problem. The problem is - all your deferred components are marked as install-time which will be used to count final APK size. Marking them as on-demand I believe will help you.
Example:
<dist:module
dist:instant="false"
dist:title="#string/audioAssetsName">
<dist:delivery>
<dist:on-demand />
</dist:delivery>
<dist:fusing dist:include="false" />
</dist:module>
Here more details: Android App Bundle: Google Play 150MB limit seems to include the Dynamic Feature Module size?
Be aware that dynamic feature APK can't exceed 150MB as well.
I want to show image (png,jpg etc) in dynamically created (as per requirement and fully through coding) TImage component, at runtime in C++ builder xe8 (not delphi). But I dont want to use opendialogbox (suggested in many web sites). I want to run this app on my android device. I tried to use LoadFromFile(), it crashes the app on android, but when I run this on windows, its running smoothly. I am just a beginner to c++ builder. So guys pls help. Thanx in advance for any kind of help.Here is what I did.
void __fastcall TForm1::TForm1(TComponent* Owner)
{
TImage* img = new TImage(this);
img->Parent = this;
img->Bitmap->LoadFromFile("D:\\res\\profile.png");
}
Did you see what is the error?
If you run the program with the provided by you code I assume the error would be that the file is not found, because there is no such directory "D:\" in android.
One way to set the path is to write a static path which points to your image. For example : "/storage/sdcard0/DCIM/Camera/MyImage.jpg";
The second way is to include the <System.IOUtils.hpp> header and to use some built-in functions like:
System::Ioutils::TPath::GetPicturesPath();
System::Ioutils::TPath::GetAlarmsPath();
You can check them out, they might be useful.
I'm new to mobile testing , and currently I research for an automation framework for mobile testing.
I've started to look into Appium, and created some tests for the demo app I've made (one for IOS and the other for Android).
I've managed to write a test for each of the platforms , but I was wondering , how difficult it might be to write a one generic test which will be executed on the both platforms with minimum adjustments ?
Thanks
It is possible but you have to keep same labels for each component for all platforms, for example to click on a button, instead of locating through Xpath locate by its name.
WebElement button = driver.findElement(By.name("my button")); button.click();
More info finding elements in Appium docs:
http://appium.wikia.com/wiki/Finding_Elements
I built an automation framework from scratch which does exactly the same thing, i.e. have one code base and the tests run both on Android and iOS based on what device and app you give the test. This is how I went about doing it. (I used Java+Appium+Cucumber framework).
Following the Page Object pattern is a good practice for writing automation code.
That being said, you will have all the resource ids of Android and Accessibility ids of iOS in 2 separate files under a folder named say "ObjectRepository". These files usually have the extension of *.properties (It is called the properties file).
Say you have a Login button that you want to interact with on Android and iOS, you have will 2 files:
File 1) "androidObject.properties" which has:
Login.LoginButton=loginAndroidBtn
File 2) "iOSObject.properties" which has:
Login.LoginButton=loginiOSBtn
NOTE: In the key/value pair above, the key is the same "Login.LoginButton", the value is the resource id and the accessibility id of the Login Button in your Android and iOS application
In your code you would do the following:
if(IS_ANDROID) {
DRIVER.findElementById("Login.LoginButton").click();
} else {
DRIVER.findElementByAccessibilityId("Login.LoginButton").click();
}
In another file you would set what IS_ANDROID and IS_IOS means. You may do something like this:
public static DeviceConfig DEVICE_CONFIG;
private void setPlatform() {
if (DEVICE_CONFIG.platformName.equals("Android")) {
IS_ANDROID = true;
} else if (DEVICE_CONFIG.platformName.equals("iOS")) {
IS_IOS = true;
}
This way you can have one code base and run Android and iOS seamlessly.
Im getting this error message. I created a new project and hit debug to test it. I added nothing and i get this pop up message. what could be my issue? I can create a new blank project wtih out the Controllers and Models projects in them it debugs just fine. But i need to use this solution provided to me.
New to mono droid any help will be apreciated.
You issue could be that none of the projects have been set to be deployed to a device.
Right click your Solution > Properties > Configuration Properties > Tick The Deploy checkbox for your Application Project if not already.
Also make sure to mark one of your activities with MainLauncher = true, otherwise Android does not know which Activity to start first. This is done in the [Activity()] attribute like so:
[Activity(Label = "Epic Activity", MainLauncher = true, Icon = "#drawable/icon")]
public class Activity1 : Activity {}
what could be my issue?
You are using Visual Studio... Android plays much nicer with Eclipse.
Kidding aside, every Android application requires an AndroidManifest.xml file. It looks like you are using MonoDroid, and there are docs about creating the manifest file.
Also, make sure you have built the project.
AndroidManifest.xml is generated as part of the build process, and the XML found within Properties\AndroidManifest.xml is merged with XML generated based on custom attributes.
I'm porting a simple tetris-like XNA app to Android, using Mono For Android and MonoGame; I have followed the suggested steps in this link and so far, everything compiles well, and no relevant warnings fire up. However, upon loading the contents, a null parameter exception breaks the program at the point below in my program:
protected override void LoadContent() {
// ...
_font = Content.Load<Microsoft.Xna.Framework.Graphics.SpriteFont>("SpriteFont1");
// ...
}
The content root directory is set in the game constructor class:
public Game2 (){
Content.RootDirectory = "Content";
Content.RootDirectory = "Assets/Content"; // TEST.
//...}
And I have tried several combinations, all to no avail.
I have also tried setting the xnb files as Content as well as Android Assets in the Build Action property; having the linked, copied always, copied only if newer... etc.
Either way, my problem is that I don't really understand WHY and HOW should I do this. I'm rather new to the platform and to XNA as well, so this may very well be a newbie question, but the truth is after several hours banging my head and fists against the monitor/keyboard I feel stuck and need your help.
I have a library that supports variable-width fonts (generated by BMFont) on MonoGame. Unfortunately it is a renderer and so has other code around it. However, the basic idea is very simple. You can take a look at the loader here and the mesh builder (given a string) here. This builder supports fonts that spread characters across multiple pages, too.
Hope this helps!
MonoGame (2.5.1) throws NotImplementedException in ContentManager.Load for SpriteFont type. Have the same not resolved problem. I'm trying not to use DrawString.
For loading textures in Win32 application I use:
Content.RootDirectory = #"../../Content";
var sampleTexture = Content.Load<Texture2D>("Sample.png");
You even must not add it to solution.
For Andoind (MonoDroid) application you must add "Content" folder to your solution and set "Andtoid Asset" in "Sample.png" properties.
Content.RootDirectory = "Content";
var sampleTexture = Content.Load<Texture2D>("Sample.png");
See also:
http://monogame.codeplex.com/discussions/360468
http://monogame.codeplex.com/discussions/267900