I am working on a feature where I need to transition user from Android Native APP to Chrome custom tab only if chrome version installed on the device is greater than version 65. So my question is, is there a way we can detect chrome version from Android Native App ?
private boolean isChromeInstalledAndVersionGreaterThan65() {
PackageInfo pInfo;
try {
pInfo = getPackageManager().getPackageInfo("com.android.chrome", 0);
} catch (PackageManager.NameNotFoundException e) {
//chrome is not installed on the device
return false;
}
if (pInfo != null) {
//Chrome has versions like 68.0.3440.91, we need to find the major version
//using the first dot we find in the string
int firstDotIndex = pInfo.versionName.indexOf(".");
//take only the number before the first dot excluding the dot itself
String majorVersion = pInfo.versionName.substring(0, firstDotIndex);
return Integer.parseInt(majorVersion) > 65;
}
return false;
}
Obviously this will work until Chrome will be versioned how they did until now, if they will decide to change the versioning the logic should be updated as well. (I don't think this will happen but for max safety put everything in a try-catch)
private boolean checkVersion(String uri) {
String versionName;
int version = 0;
PackageManager pm = getPackageManager();
try {
versionName = pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES).versionName;
String[] split = versionName.split(Pattern.quote("."));
String major = split[0];
version = Integer.parseInt(major);
return version > 65;
} catch (PackageManager.NameNotFoundException e) {
//Catch the Exception
}
return false;
}
Then call above method using
checkVersion("com.android.chrome"); //This will return a boolean value
Related
I have a Marshmallow device. It has custom built SW.
I have seen the build.prop file. There I can perceive the Software version name comes from ro.custom.build.version
My question is - how can I get the "ro.custom.build.version" information programmatically in my application ?
I got the answer. It is very simple -
First, I created a function to read from SystemProperties.
public String getSystemProperty(String key) {
String value = null;
try {
value = (String) Class.forName("android.os.SystemProperties")
.getMethod("get", String.class).invoke(null, key);
} catch (Exception e) {
e.printStackTrace();
}
return value;
}
And then called the function with "ro.custom.build.version" as a key
getSystemProperty("ro.custom.build.version");
Special thanks to #sasikumar for giving me the hint
You have to do as below :
PackageInfo pInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
String version = pInfo.versionName;
To get the Version code, Use as below :
int verCode = pInfo.versionCode;
Check android.os.Build.VERSION. You can use INCREMENTAL.
I'm trying to use the SecureRandom workaround that Google posted in my android application:
http://android-developers.blogspot.com/2013/08/some-securerandom-thoughts.html
This work around involve writing to (and reading from) /dev/urandom. However, it looks like Samsung has enabled SELinux in such a way that prevents applications from accessing /dev/urandom.
I don't have one of these devices, so it is a little hard for me to test solutions, other than to push out attempts at workarounds on the Android market, but it seems like this is not an error that I can trap with a try catch block. It also appears that File.canRead and canWrite return true. You can see my attempts at workaround in the supportedOnThisDevice method in the following class:
PRNGFixes.java
I'm looking for a reliable way to detect if I am an such a device, and if so, not apply the Google SecureRandom workaround.
This is my way to check if SELinux is in enforce-mode - can be done via any Shell-script, not depending on RootTools:
private static boolean isSELinuxEnforcing() {
try {
CommandCapture command = new CommandCapture(1, "getenforce");
RootTools.getShell(false).add(command).waitForFinish();
boolean isSELinuxEnforcing = command.toString().trim().equalsIgnoreCase("enforcing");
return isSELinuxEnforcing;
} catch (Exception e) {
// handle exception
}
return false;
}
I've heard Samsung is starting to ship devices with the SELinux policy set to Enforce, but I don't know if it's true or not. As far as I know most devices on 4.3 still have it set to permissive.
According to Google, "SELinux reinforcement is invisible to users and developers, and adds robustness to the existing Android security model while maintaining compatibility with existing applications." So you may need to check the system properties or test it through a shell to find out for sure.
If you can get someone to send you their build.prop you may be able to catch it by comparing their ro.build.selinux property via System.getProperty("ro.build.selinux"),
but you'll also want to verify you're able to access it more directly in case it is unreliable or getProperty() for that is broken in future updates.
Root (System user on SELinux) is another option when available, but either way a shell based solution is probably your best bet.
System.getProperty("ro.build.selinux")
Did not work for me on Samsung S4 Android 4.3. So I wrote this
private static final int JELLY_BEAN_MR2 = 18;
public static boolean isSELinuxSupported() {
// Didnt' work
//String selinuxStatus = System.getProperty(PROPERTY_SELINUX_STATUS);
//return selinuxStatus.equals("1") ? true : false;
String selinuxFlag = getSelinuxFlag();
if (!StringUtils.isEmpty(selinuxFlag)) {
return selinuxFlag.equals("1") ? true : false;
} else {
// 4.3 or later ?
if(Build.VERSION.SDK_INT >= JELLY_BEAN_MR2) {
return true;
}
else {
return false;
}
}
}
public static String getSelinuxFlag() {
String selinux = null;
try {
Class<?> c = Class.forName("android.os.SystemProperties");
Method get = c.getMethod("get", String.class);
selinux = (String) get.invoke(c, "ro.build.selinux");
} catch (Exception ignored) {
}
return selinux;
}
if you have access to the frameworks
import android.os.SELinux;
SELinux.isSELinuxEnforced();
Most devices as as of Jellybean MR2 and onwards will have SELinux enabled on their devices, but if you are working with OEMs or doing platform work this might not necessarily be true.
The method I am using to verify is with the getenforce shell command:
public boolean isSeLinuxEnforcing() {
StringBuffer output = new StringBuffer();
Process p;
try {
p = Runtime.getRuntime().exec("getenforce");
p.waitFor();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
while ((line = reader.readLine())!= null) {
output.append(line);
}
} catch (Exception e) {
Log.e(TAG, "OS does not support getenforce");
// If getenforce is not available to the device, assume the device is not enforcing
e.printStackTrace();
return false;
}
String response = output.toString();
if ("Enforcing".equals(response)) {
return true;
} else if ("Permissive".equals(response)) {
return false;
} else {
Log.e(TAG, "getenforce returned unexpected value, unable to determine selinux!");
// If getenforce is modified on this device, assume the device is not enforcing
return false;
}
}
It appears that most devices are only writing a system property for selinux if they aren't running in enforcing status. You can additionally check the property: ro.boot.selinux to see if the Kernel passed in the permissive parameter on your current build.
This question already has an answer here:
Identifying if an app exists, if not go to play store
(1 answer)
Closed 9 years ago.
Could I know If there is a specific app installed in the phone programmatically? My app would make a process in one way or in other depending on that. How could I get this information?
Thanks!!
private boolean isAppInstalled(String packageName) {
PackageManager pm = getPackageManager();
boolean installed = false;
try {
pm.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES);
installed = true;
} catch (PackageManager.NameNotFoundException e) {
installed = false;
}
return installed;
}
You must know the package name to check weather the application is installed or not
say if package name is like com.myapp.name
use the following to existence
boolean isExists;
try
{
getPackageManager().getPackageInfo("com.myapp.name", PackageManager.GET_ACTIVITIES);
isExists = true;
}
catch(NameNotFoundException e)
{
isExists = false;
// Sep 11, 2013 8:39:47 PM
Log.e("Exception", "NameNotFoundException" + String.valueOf(e.getMessage()));
e.printStackTrace();
}
Must use try catch around to handling expected error when NameNotFoundException is thrown
I'm adapting an app so it will work on the KindleFire, which doesn't have a camera.
I don't have any Android devices that lack a camera, so I don't know if the following code actually will return false for the Kindle. I'm using reflection because my app has already been released with Donut compatibility, and Donut doesn't have PackageManager.hasSystemFeature().
I'm assuming Donut devices all have cameras--hasn't caused me trouble yet.
public static boolean isCameraAvailable(Context context){
PackageManager pm = context.getPackageManager();
return tryHasSystemFeature(pm,"android.hardware.camera");
}
private static Method packageManager_hasSystemFeature;
static {
initCompatibility();
};
private static void initCompatibility() {
try {
packageManager_hasSystemFeature = PackageManager.class.getMethod(
"hasSystemFeature", new Class[] { String.class } );
} catch (NoSuchMethodException nsme) {
//leave the Method null
}
}
static private boolean tryHasSystemFeature(PackageManager pm,String feature){
if (packageManager_hasSystemFeature != null) {
try {
final Boolean hasIt = (Boolean) packageManager_hasSystemFeature.invoke(pm,feature);
return hasIt.booleanValue();
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}
return true;
}
Actually it's recommended to add this line in your manifest file, if you want to be sure the device has a camera:
<uses-feature android:name="android.hardware.camera" />
Market will prevent a device without a camera from downloading your application.
We have a set of 3-5 android applications that we have developed for an enterprise to integrate with our back-end. How do we create an installer system that upgrades applications automatically. We were thinking of getting version numbers and querying the backend to get current versions and downloading them.
How do I get the version number of an application in Android?
ApplicationInfo info = getApplicationInfo();
try {
info = getPackageManager().getApplicationInfo(info.packageName, PackageManager.GET_META_DATA);
} catch (NameNotFoundException e) {
e.printStackTrace();
}
Any pointers will be most useful.
Thanks
Sameer
Using the function below you can get the current Version Name or No for the application.
This you can check against that of the app at server side and if needed you can upgrade app.
public static function String getVersionName(Context context, Class cls) {
try {
ComponentName comp = new ComponentName(context, cls);
PackageInfo pinfo = context.getPackageManager().getPackageInfo(comp.getPackageName(), 0);
return pinfo.versionName;
} catch (android.content.pm.PackageManager.NameNotFoundException e) {
return null;
}
}