openOptionsMenu does not work: wrong SDK? - android

I use openOptionsMenu() to open the menu in applications with special GUI - for example, apps that only show graphics (fullscreen apps without toolbars etc.), upon a long press of the screen.
I can see that I made it work in the past on other applications, and I suppose that it was by using in the Manifest,
android:minSdkVersion="15"
android:targetSdkVersion="15"
I am now unable to make this work (the code would be):
myButton.setOnLongClickListener(
new OnLongClickListener() {
#Override public boolean onLongClick(View v) {
openOptionsMenu();
return false;
}
}
);
I think that Android Studio is using the wrong SDK. In fact,
the values I put in the Manifest ("min" and "target" set to 15) are overridden;
the values used should be those of build.gradle - and again, I set "compile", "min" and "target" set to 15, but I do not see the app
working properly and I think the SDK selection may not be happening;
as I check the produced APK the Manifest entries for the SDK (minSdkVersion, targetSdkVersion) are missing.
The build.gradle file according to the Android Studio interface shows:
android {
compileSdkVersion 15
buildToolsVersion "28.0.2"
defaultConfig {
applicationId '[...AppID...]'
minSdkVersion 15
targetSdkVersion 15
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
productFlavors {
}
}
As written above, the AndroidManifest.xml in the compiled APK (after apktool -d) does not mention any SDK selection.
I expect that the app compiled for SDK 15 would open the (very required) menu upon call of openOptionsMenu(). What the compiled app does now, upon debugging, is to go instead in the method that would /close/ the menu (clearly a satanic intention).
EDIT: the information about the specific case of Google butchering openOptionsMenu() after some SDK version is at
openOptionsMenu function not working in ICS?

I suppose I have made a mistake.
I realized that my past, working code did not just compile for SDK 15, it also contained an override as follows, and as suggested by user tallicalord in the previously linked page:
#Override public void openOptionsMenu() {
Configuration cfg = getResources().getConfiguration();
if( (cfg.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK)>Configuration.SCREENLAYOUT_SIZE_LARGE){
int shelf = cfg.screenLayout;
cfg.screenLayout = Configuration.SCREENLAYOUT_SIZE_LARGE;
super.openOptionsMenu();
cfg.screenLayout = shelf;
}else{
super.openOptionsMenu();
}
}
So it is possible that the SDK selection, even though more mysterious in Android-Gradle (which removes references in the Manifest), was not the problem.
I shall note that it is very unfortunate how Google manages to make people waste uncountable hours for problems that did not need to exist at all.

Related

Android Studio-Generate Signed APK Errors

I recently started Androids Studio, I bought a quiz game and I tried to modify it a bit with the help of some tutorials, only when I want to generate the apk I get some errors, I tried to do everything from the beginning about 10 times and the same, I don't know where I'm wrong, you have below a link with a video with the errors. Thank you in advance!!!
https://www.youtube.com/watch?v=59fxv4F5DYE
I guess you are getting an error due to using Vector drawables which are supported on Android API 21 and above and your minSdk is lower than 21. The solution to this is either update your minSdk version to be at least 21.
Or in your gradle.build:
android {
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
}
And in application class define this:
#Override
public void onCreate() {
super.onCreate();
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
And when using the resource for example in your ImageView:
<ImageView
...
app:srcCompat="#drawable/ic_some_vector" />

How to detect android wear 1.0 and 2.0

i have successfully made a project apk which allow the watch download the wear app. And i am trying to use that wearable code to support standalone for wear 2.0 as well - seem not much resources in the internet.
my question is how to determine if the wearable device is 1.0 or 2.0. i made use of productFlavors based on this link as follows:
android {
// Allows you to reference product flavors in your
// phone module's build.gradle file
publishNonDefault true
...
defaultConfig
{
// This is the minSdkVersion of the Wear 1.x embedded app
minSdkVersion 23
...
}
buildTypes {...}
productFlavors {
wear1 {
// Use the defaultConfig value
}
wear2 {
minSdkVersion 25
}
}
}
As i recalled, wear 1.0 usually collect data from phone and wear 2.0 has ability to access data via the internet. Please correct me if i am wrong.
So if the wearable is 1.0, it uses Wearable.API and sync with the phone. Otherwise, the wearable sync with cloud.
I had a look on this post which seems useful but i do not quite understand.
PackageManager pm = getApplicationContext().getPackageManager();
pm.getPackageInfo(packagename, PackageManager.GET_ACTIVITIES);
Should i set a different packagename(or applicationId) for wear2 so that i can use this method?
is there any drawback when i put standalone version on play store? i suppose i have to create a new project in this way.
Please can anyone advise the best way to achieve my purpose?
If you want to distribute and maintain two separate APKs, then the build flavor is probably a reasonable way to go. But I would suggest that this won't be a good experience for either you or your users; it's more work for you, and it'll be confusing for them (which version do I install? why doesn't this app work after I my watch upgraded to Wear 2.0? and so on).
My suggestion would be to put it all in one APK, and simply choose which sync technique to use at run time:
if (Build.VERSION.SDK_INT < 24) {
// Wear 1.x
} else {
// Wear 2+
}

Can I enable multidex in Android debug build only?

Dears,
I read in many blog posts that multidex apps startup is slower than normal apps.
My app uses a lot of libraries that exceed 64k methods so I use multidex. But when I use proguard in release build, the final apk becomes less than 64k methods
So My question is: Can I enable multidex in Android debug build only so I don't have runtime error? and disable multi dex in release build as I don't need it?
If yes, how ?
If No, Is Android smart enough to speedup startup as it should recognize that app didn't exceed 64k even if it is multi dex app ?
Yes, you can. When you declare your buildTypes include multidex only for debug:
buildTypes {
release {
multiDexEnabled false
    }
debug {
multiDexEnabled true
}
}
Instead of enabling multidex only for debug, you can change your min sdk version to 21 only for debug so gradle can speed up dexing with ART:
android {
productFlavors {
// Define separate dev and prod product flavors.
dev {
// dev utilizes minSDKVersion = 21 to allow the Android gradle plugin
// to pre-dex each module and produce an APK that can be tested on
// Android Lollipop without time consuming dex merging processes.
minSdkVersion 21
}
prod {
// The actual minSdkVersion for the application.
minSdkVersion 14
}
}
...
buildTypes {
release {
runProguard true
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-rules.pro'
}
}
}
dependencies {
compile 'com.android.support:multidex:1.0.0'
}
http://developer.android.com/tools/building/multidex.html
suggested methods are not needed anymore as android studio became "smart enough".
In fact, it will now give you a warning when you use minSdkVersion 21 (the old way) to speed up build time with dex:
You no longer need a dev mode to enable multi-dexing during
development, and this can break API version checks less...
In the past, our documentation recommended creating a dev product
flavor with has a minSdkVersion of 21, in order to enable multidexing
to speed up builds significantly during development. That workaround
is no longer necessary, and it has some serious downsides, such as
breaking API access checking (since the true minSdkVersion is no
longer known.) In recent versions of the IDE and the Gradle plugin,
the IDE automatically passes the API level of the connected device
used for deployment, and if that device is at least API 21, then
multidexing is automatically turned on, meaning that you get the same
speed benefits as the dev product flavor but without the downsides.
Yes, it even works with the multidex support library for Android versions prior to Lollipop with a little trick.
First specify multiDexEnabled for the debug build in build.gradle:
buildTypes {
...
debug {
...
multiDexEnabled true
}
}
Then create an AndroidManifest.xml file under src/debug.
src/debug/AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:name="android.support.multidex.MultiDexApplication"
tools:replace="android:name"/>
</manifest>
That should do the trick. If your app uses a custom application class then you have to create a subclass of your application class and specify the name of that subclass in the manifest.
The application subclass should look like this:
public class MyDebugApplication extends MyApplication {
#Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
}

gradle - Android Studio build too slow multidex application

When I add to my project the multidex:true, and make an Application class that extends from the MultiDexApplication, my project build time passed from 20 sec to around 90 sec.How to do some faster?
If you are like me who already tried Vic Vu's solution but still can't avoid enabling multiDex then you can try this (as long as your are using a device that has Android 5.0 and above).
Note This will only speed up your development build. Your production build will still be slow.
Basically you need to introduce 2 product flavors one for dev and one for prod.
Add multiDexEnabled true
android {
productFlavors {
// Define separate dev and prod product flavors.
dev {
// dev utilizes minSDKVersion = 21 to allow the Android gradle plugin
// to pre-dex each module and produce an APK that can be tested on
// Android Lollipop without time consuming dex merging processes.
minSdkVersion 21
}
prod {
// The actual minSdkVersion for the application.
minSdkVersion 14
}
}
...
buildTypes {
release {
runProguard true
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-rules.pro'
}
defaultConfig {
applicationId "com.something.something"
targetSdkVersion 23
versionCode 1
versionName "1.0.0"
multiDexEnabled true
}
}
dependencies {
compile 'com.android.support:multidex:1.0.1'
}
And I have a class which extends Application so I had to override attachBaseContext()
#Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
If you are not extending Application simply use MultiDexApplication in your AndroidManifest.xml application tag.
Ensure that in your Android Studio Build Variants you are pointing to devDebug.
Read the complete instructions here https://developer.android.com/studio/build/multidex.html#dev-build
Supplying as an answer because this is better fit with the formatting.
To simply answer your question: No, there is no way. Multidex is a process meant to help lift the burden of the 65k method limit. This process is complicated and will simply make your build times longer.
The best you can can do is lower your method count.
In your build.gradle (supplied here) you're using:
`compile 'com.google.android.gms:play-services:8.3.0'`
But if you look at the most recent play services api you can pick and choose what services you actually need.
Look at Table 1 on this page.
Only use the ones you need. Google play services as a whole is somewhere around 30k methods.
That should help.
Multidexing uses more memory. As you get closer to your max heap size in Java you'll find Java spends more time doing GC than it does doing any real work, this can slow things down a lot.
I'd strongly recommend increasing the max heap size when using multidex. Add the following to the android closure in your build.gradle file to make the max heap size 4GB (Make it larger/smaller if you wish):
dexOptions {
javaMaxHeapSize "4g"
}
It depends.
You haven't specified it in your question, but if you just want to speed-up your development builds - then you can avoid the extra work. Official documentation includes a whole section about that.

Unable to open debugger port : java.net.SocketException “Socket closed”

I'm using Android Studio, with multiple flavors using Gradle, each with a Debug and Release type, organized as described here, on the bottom half.When I try to start the debugger, I get this error:
Error running androidRecover [installAppDebug]: Unable to open debugger port : java.net.SocketException "Socket closed
I'm also unable to attach the debugger to my device once it's running (it only displays the name of my phone, not the app).
All 3 flavors install on my phone just fine. I just can't get it to let me debug them. I also tested attaching the debugger on a Nexus tablet, and I got the same result.
It's not Gradle specifically as a whole because I can run other Gradle-based apps and attach the debugger just fine so I wonder if it's something with how I've setup my Gradle project and settings.
Here's my build.gradle:
apply plugin: 'android'
apply from: 'signing.gradle'
android {
compileSdkVersion 19
buildToolsVersion '19.0.3'
defaultConfig {
minSdkVersion 8
targetSdkVersion 19
}
buildTypes {
release {
runProguard false
proguardFiles getDefaultProguardFile
('proguard-android.txt'), 'proguard-rules.txt'
}
}
productFlavors {
flav1 {
packageName "com.ex.flav1"
versionCode 32
versionName "1.0.5"
signingConfig signingConfigs.flav1
}
flav2 {
packageName "com.ex.flav2"
versionCode 33
versionName "1.0.6"
signingConfig signingConfigs.flav2
}
flav3 {
packageName "com.ex.flav3"
versionCode 27
versionName "1.0.0"
signingConfig signingConfigs.flav3
}
}
}
dependencies {
compile 'com.android.support:appcompat-v7:19.+'
compile fileTree(dir: 'libs', include: ['*.jar'])
compile files('libs/httpmime-4.2.5.jar')
}
I really have no idea what else to try. Android Studio is completely up-to-date. I've restarted Android Studio, my phone, and my computer.
Also, last week I was having this problem, but it was a specific socket that was blocked, from trying to run the emulator and my phone at the same time. I also noticed I had multiple Gradle processes running, because it wasn't killing them on its own, which I often had to kill Android Studio to kill them. Once that was fixed, it was working off and on.
Let me know if you need any other info.
Thanks,
Devin
Edit I finally know why #hasanaydogar's answer works and why it probably would have solved my problem if we had known it then. See my 2nd comment on it to know why, but in short, you have to select in that dropdown the name that matches your app's root directory.
Just Click the button (left side the RUN button).
Select Android. Then Run.
It will connect to your device.
And dont forget to change build variant
I finally understand why I was getting that error so I'm going to explain how I Debug now. Note that I use Gradle (build multiple apk's using the same code), which might influence some how you use the third part of this answer.
For these to work, in the dropdown next to the debug (icon in #1) and run buttons in the top toolbar, you have to have the one selected with the following icon next to it because that's the name of the root directory of your app where all your code lives:
To start debugging from the beginning, I run the app in Debug mode from the start, using this button in your toolbar:
To attach the debugger to the app when it's already running as #scottyab mentioned, I click the Attach Debugger button in your toolbar:
To run the release version of my app in debug mode, I've started changing my strings in the Debug version of strings.xml in the file path myApp/src/appNameDebug(verses appNameRelease)/res/values/strings.xml, more easily seen here, on the bottom half. When I say change, I really mean that I have two versions of all the strings (3 in my case) necessary to change from using the debug server to using the release server. It might not be completely kosher, but it takes about 5 seconds to go the file, and hold down Cmd+/ and uncomment and comment all of the appropriate lines.
My Release version is just there for when I'm ready to build an apk for release.
Doing things in this way has eliminated that error popping up anymore. I think the Release version is just not made for debugging, and I haven't found an easy way to turn the debug flags on when in Release mode.
I managed to get this working by attaching the debugger after a build see Unable to open debugger port : java.net.SocketException "Socket closed"
I managed to get rid of this problem by killing & restart the adb process,hope this would help :]
I have solved this question with reference to the following SO Answer
The "Select Run/Debug Configuration" button in android studio 2.3.2
Change the Debug type to Native

Categories

Resources