How to fix error get app version on Android 12? - android

I used this code and it can only get the version of other app above Android 11 and earlier. On Android 12 it doesn't work.
String uri = "com.uptodown.installer";
android.content.pm.PackageManager pm = getPackageManager(); try { android.content.pm.PackageInfo pInfo = pm.getPackageInfo(uri, android.content.pm.PackageManager.GET_ACTIVITIES); String version = pInfo.versionName;textview.setText(version); } catch (android.content.pm.PackageManager.NameNotFoundException e) { }
I tried to try but it only works on Android 11 or earlier.

From what I can tell, getPackageInfo() is deprecated as you've used it. From the ide:
Deprecated
Use getPackageInfo(String, PackageManager.PackageInfoFlags) instead.

Related

How to know an app's target sdk version

I'm doing some android analysis and need to find all the android app that have targetSdkversion over 23, right now I'm reverse engineering all the apk packages to see this...Wondering if there's more easy way to get this information given an app name?
Thanks :)
you can do that by this code:
int sdkVersion = 0;
IPackageManager packageManager = AppGlobals.getPackageManager();
try {
ApplicationInfo appInfo = packageManager.getApplicationInfo(yourAppName, 0);
if (applInfo != null) {
sdkVersion = applicationInfo.targetSdkVersion;
}
}

Android MediaMetadataRetriever fails to load metadata on old Samsung devices

I'm facing a strange issue when using the android.media.MediaMetadataRetriever. It fails to extract the video width from video files on Samsung phones with Android version 4.0.4 and 4.1.2. The call metaRetriever.extractMetadata() seems to return either null or an empty string, as users of my app are reporting the VideoSetupException with error code ASVF_3.
It works on the Google emulators with said Android versions and all other Android versions and devices.
Any idea what might be causing this? It seems to me that there is a bug in the Android version distributed by Samsung.
Thanks a lot.
M.
private void setVideoViewDimensionToMatchVideoMetadata(VideoView videoView, Uri uri) {
String metadataVideoWidth;
String metadataVideoHeight;
try {
final MediaMetadataRetriever metaRetriever = new MediaMetadataRetriever();
metaRetriever.setDataSource(getActivity(), uri);
metadataVideoWidth = metaRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH);
metadataVideoHeight = metaRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT);
metaRetriever.release();
} catch (NullPointerException | IllegalArgumentException ex) {
throw new VideoSetupException(getActivity().getString(R.string.ASVF_2)
+ StringUtils.SPACE + ex.getLocalizedMessage(), ex);
}
if (StringUtils.isEmpty(metadataVideoWidth)) {
throw new VideoSetupException(getActivity().getString(R.string.ASVF_3));
}

How to know a process of an app is 32-bit or 64-bit programmatically in Android lollipop?

As we all know from Android 5.0.64bit support is there. I have very simple question. Can we check programmatically in what mode any application is running i.e. 32bit or 64bit? For example: I have Facebook app running on my Nexus 9, so can I check using my android app if Facebook app's process is running in 32bit mode or 64bit mode?
In Nexus 5x
String arch = System.getProperty("os.arch");
returns
armv8l
it is not aarch64 and my code broke. However,
root#bullhead:/ # uname -m
aarch64
root#bullhead:/ # getprop ro.product.cpu.abilist
arm64-v8a,armeabi-v7a,armeabi
Wired. So I changed my code to
boolean is64 = (android.os.Build.VERSION.SDK_INT >= 21) && System.getProperty("ro.product.cpu.abilist").contains("64");
Updated on 2016-02-11
In Samsung Samsung Galaxy S5 Neo, Android 5.1.1
String arch = System.getProperty("os.arch");
returns aarch64 but it is not 64-bit device!!!
ro.product.cpu.abilist returns armeabi-v7a,armeabi
bool is64Bit = System.getProperty("ro.product.cpu.abilist").contains("64");
check is the only way to check.
Try System.getProperty("os.arch").
I haven't tried it on 64-bit android, but it must return something like 'aarch64' in case of 64 bit device.
http://developer.android.com/reference/java/lang/System.html#getProperty(java.lang.String)
public static boolean is64Bit() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
//Added in API level 23
return Process.is64Bit();
}
try {
Class cls = Class.forName("dalvik.system.VMRuntime");
Method getRuntimeMethod = cls.getDeclaredMethod("getRuntime");
Object vmRuntime = getRuntimeMethod.invoke(null);
Method is64BitMethod = cls.getDeclaredMethod("is64Bit");
Object is64Bit = is64BitMethod.invoke(vmRuntime);
if (is64Bit instanceof Boolean) {
return (boolean) is64Bit;
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
IMO, you can use reflect to get the result of is64Bit. Android 6.0 began to provide this api to check your process.
android.os.Process.is64Bit()
In my experience (if your minSdkVersion is >= 21) the best way is to check the size of the array Build.SUPPORTED_64_BIT_ABIS.
(see https://developer.android.com/reference/android/os/Build#SUPPORTED_64_BIT_ABIS)
Something like this:
public static boolean is64Bit() {
return (Build.SUPPORTED_64_BIT_ABIS!= null && Build.SUPPORTED_64_BIT_ABIS.length >0);
}
What makes you think your device isn't 64-bit? The specs for the phone indicate it uses an Exynos 7 Octa 7580 which is arm8 and 64-bit.
boolean is64Arch = Build.CPU_ABI.equalsIgnoreCase("x86_64") || Build.CPU_ABI.equalsIgnoreCase("arm64-v8a");

Android & calling methods that current API doesnt have

If i want to get the external path like this, and device has Android 2.1 (api 7)
File f;
int sdkVersion = Integer.parseInt(Build.VERSION.SDK);
if (sdkVersion >= 8) {
System.out.println(">=8");
f = getApplicationContext().getExternalFilesDir(null);
} else {
System.out.println("<=7");
f = Environment.getExternalStorageDirectory();
}
LogCat will display:
05-25 15:44:08.355: W/dalvikvm(16688): VFY: unable to resolve virtual method 12: Landroid/content/Context;.getExternalFilesDir (Ljava/lang/String;)Ljava/io/File;
, but app will not crush. I want to know what is VFY? Is there something in the virtual machine dalvik that checks if code inside a called method is valid? Because current proj was compiled agains Android 2.2 so Eclipse didn't complained.. but at runtime, i get LogCat entry
PS: i dont use method like this in really, i have Helper class which initialises a class for API<=7 or another for API>=8.. but still please answer!
Yes, VFY errors are logged from dex verifier in dalvik.
You are facing this issue because you are performing runtime checks for the SDK version and calling the API methods. The problem is even if the method call is inside the if(){} block which may never be executed in lower API levels, the symbolic information is present in the generated bytecode. If you need to perform platform specific function calls, you need to use reflection.
File f;
int sdkVersion = Integer.parseInt(Build.VERSION.SDK);
if (sdkVersion >= 8) {
System.out.println(">=8");
try {
Method getExternalFilesDir = Context.class.getMethod("getExternalFilesDir", new Class[] { String.class } );
f = (File)getExternalFilesDir.invoke(getApplicationContext(), new Object[]{null});
} catch (Exception e) {
e.printStackTrace();
}
} else {
System.out.println("<=7");
f = Environment.getExternalStorageDirectory();
}

Retrieving Android API version programmatically

Is there any way to get the API version that the phone is currently running?
As described in the Android documentation, the SDK level (integer) the phone is running is available in:
android.os.Build.VERSION.SDK_INT
The class corresponding to this int is in the android.os.Build.VERSION_CODES class.
Code example:
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP){
// Do something for lollipop and above versions
} else{
// do something for phones running an SDK before lollipop
}
Edit: This SDK_INT is available since Donut (android 1.6 / API4) so make sure your application is not retro-compatible with Cupcake (android 1.5 / API3) when you use it or your application will crash (thanks to Programmer Bruce for the precision).
Corresponding android documentation is here and here
Very easy:
String manufacturer = Build.MANUFACTURER;
String model = Build.MODEL;
int version = Build.VERSION.SDK_INT;
String versionRelease = Build.VERSION.RELEASE;
Log.e("MyActivity", "manufacturer " + manufacturer
+ " \n model " + model
+ " \n version " + version
+ " \n versionRelease " + versionRelease
);
Output:
E/MyActivity: manufacturer ManufacturerX
model SM-T310
version 19
versionRelease 4.4.2
Build.VERSION.RELEASE;
That will give you the actual numbers of your version; aka 2.3.3 or 2.2.
The problem with using Build.VERSION.SDK_INT is if you have a rooted phone or custom rom, you could have a non standard OS (aka my android is running 2.3.5) and that will return a null when using Build.VERSION.SDK_INT so Build.VERSION.RELEASE will work no matter using standard Android version or not !
To use it, you could just do this;
String androidOS = Build.VERSION.RELEASE;
try this:
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.GINGERBREAD) {
// only for gingerbread and newer versions
}
Taking into account all said, here is the code I use for detecting if device has Froyo or newer Android OS (2.2+):
public static boolean froyoOrNewer() {
// SDK_INT is introduced in 1.6 (API Level 4) so code referencing that would fail
// Also we can't use SDK_INT since some modified ROMs play around with this value, RELEASE is most versatile variable
if (android.os.Build.VERSION.RELEASE.startsWith("1.") ||
android.os.Build.VERSION.RELEASE.startsWith("2.0") ||
android.os.Build.VERSION.RELEASE.startsWith("2.1"))
return false;
return true;
}
Obviously, you can modify that if condition to take into account 1.0 & 1.5 versions of Android in case you need generic checker. You will probably end up with something like this:
// returns true if current Android OS on device is >= verCode
public static boolean androidMinimum(int verCode) {
if (android.os.Build.VERSION.RELEASE.startsWith("1.0"))
return verCode == 1;
else if (android.os.Build.VERSION.RELEASE.startsWith("1.1")) {
return verCode <= 2;
} else if (android.os.Build.VERSION.RELEASE.startsWith("1.5")) {
return verCode <= 3;
} else {
return android.os.Build.VERSION.SDK_INT >= verCode;
}
}
Let me know if code is not working for you.
android.os.Build.VERSION.SDK should give you the value of the API Level. You can easily find the mapping from api level to android version in the android documentation. I believe, 8 is for 2.2, 7 for 2.1, and so on.
SDK.INT is supported for Android 1.6 and up
SDK is supported for all versions
So I do:
String sdk_version_number = android.os.Build.VERSION.SDK;
Credits to: CommonsWare over this answer
Got it. Its using the getApplicationInfo() method of the Context class.
I generally prefer to add these codes in a function to get the Android version:
int whichAndroidVersion;
whichAndroidVersion= Build.VERSION.SDK_INT;
textView.setText("" + whichAndroidVersion); //If you don't use "" then app crashes.
For example, that code above will set the text into my textView as "29" now.
i prefer have the version as number to be handeled more easyway than i wrote this:
public static float getAPIVerison() {
Float f = null;
try {
StringBuilder strBuild = new StringBuilder();
strBuild.append(android.os.Build.VERSION.RELEASE.substring(0, 2));
f = new Float(strBuild.toString());
} catch (NumberFormatException e) {
Log.e("", "error retriving api version" + e.getMessage());
}
return f.floatValue();
}
I improved code i used
public static float getAPIVerison() {
float f=1f;
try {
StringBuilder strBuild = new StringBuilder();
strBuild.append(android.os.Build.VERSION.RELEASE.substring(0, 2));
f= Float.valueOf(strBuild.toString());
} catch (NumberFormatException e) {
Log.e("myApp", "error retriving api version" + e.getMessage());
}
return f;
}
Like this:
String versionRelease = BuildConfig.VERSION_NAME;
versionRelease :- 2.1.17
Please make sure your import package is correct ( import package your_application_package_name, otherwise it will not work properly).

Categories

Resources