I have an application which I wanted to running it on only physical devices, that means no virtual devices like Android emulator. If user tries to install or run it on emulator it must exit the application. Please provide restricting logic for the same. TIA
you can check whether the app is running on android emulator or not with this method. then if it is running on android emulator you can decide to finish activity (or whatever you decide)
fun isRunningOnEmulator(): Boolean {
var result = (Build.FINGERPRINT.startsWith("generic")
|| Build.FINGERPRINT.startsWith("unknown")
|| Build.MODEL.contains("google_sdk")
|| Build.MODEL.contains("Emulator")
|| Build.MODEL.contains("Android SDK built for x86")
|| Build.MANUFACTURER.contains("Genymotion"))
if (result)
return true
result = result or (Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic"))
if (result)
return true
result = result or ("google_sdk" == Build.PRODUCT)
return result
}
if this is not working you might want to give this library a try :
android-emulator-detector
if this library is old you might want to checkout this fork which also detects nox emulator
android-emulator-detector forked by daiwei92
Related
I am trying to do a TTS app for Arabic however whenever I want to initialize my TTS it always fails. I have no idea what I'm supposed to do to fix it. I tried to enter the TTS engine on the emulator but it doesn't show me anything. So I'm unsure whether the issue is from the emulator or my code.
TTS = new TextToSpeech(this, new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
if (status==TextToSpeech.SUCCESS){
int res = TTS.setLanguage(Locale.forLanguageTag("ar-XA"));
if (res == TextToSpeech.LANG_MISSING_DATA || res == TextToSpeech.LANG_NOT_SUPPORTED){
Log.e("TTS","Language not Supporter");
}
else{
speak.setEnabled(true);
}
}
else{
Log.e("TTS","Init Failed");
}
}
});
This is some information that may help you get TTS working on an android emulator.
When I first tried your code I got the LANG_NOT_SUPPORTED error but soon realized my particular emulator instance did not have an TTS engine installed.
To install a TTS engine with an emulator I then had to use an emulator with Google Play (only a small subset of the AVD emulators have them). From the Android Virtual Device Manager you can Create Virtual Device and see (under phone for example) a few with Play Store: Pixel 4, Pixel 3a, Pixel 3, Pixel, Nexus 5X, Nexus 5.
I then used the Nexus 5 with API 25. (I already had it created.)
With the the emulator running I can then see the Play Store app listed. Run the Play Store app as you would on a phone (you'll have to authenticate yourself with your google account just as you would on a phone). Use the search bar and search for "speech services by google" - and install this app if not already installed. This is one TTS engine example which worked for me. Since this is the only TTS engine installed it is also the default. So if you choose to load other engines then you would have select the proper engine. (The engine name is a package name such as com.google.android.tts.)
I then ran your code (slightly modified) as in the following. I added some diagnostics to list the available languages and variants. I also reviewed the available languages and regions here: https://cloud.google.com/speech-to-text/docs/languages and for example just chose "ar-iq" (but "ar" also worked).
Note your "ar-XA" is a language tag used for voices and not for the engine language.
TTS = new TextToSpeech(this, new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
if (status==TextToSpeech.SUCCESS){
Set<Locale> avail = TTS.getAvailableLanguages();
for (Locale locale : avail) {
Log.e(TAG,"local: "+locale);
if (locale.getDisplayVariant() != null) {
Log.e(TAG," var: "+locale.getVariant());
}
}
List<TextToSpeech.EngineInfo> engineInfo = TTS.getEngines();
for (TextToSpeech.EngineInfo info : engineInfo) {
Log.e(TAG,"info: "+info);
}
int res = TTS.setLanguage(Locale.forLanguageTag("ar-iq"));
if (res == TextToSpeech.LANG_MISSING_DATA || res == TextToSpeech.LANG_NOT_SUPPORTED){
Log.e("TTS","Language not Supporter");
}
else{
//speak.setEnabled(true);
TTS.speak("اَلْعَرَبِيَّةُ", TextToSpeech.QUEUE_ADD, null);
}
}
else{
Log.e("TTS","Init Failed");
}
}
});
Once you have the TTS engine installed and your code or above code works - I think you can then use Settings to install your voice data:
Settings | Speech | Text-to-speech output | (choose Speech Services by Google) and select the gear icon | and select your voice data.
You could also use the voice data programmatically.
Note you can install another TTS engine (not the default) by using the constructor:
TextToSpeech(Context context, TextToSpeech.OnInitListener listener, String engine)
The Arabic voices which come with the Google TTS engine have the following language tags - I'm guessing that when the language is set a preferred voice is used which is one of these:
ar-xa-x-arz-local
ar-xa-x-arc-local
Why isOperational() in mobile vision text recognizer returns false?
At first, mobile vision only show preview camera and after many tries to get the result, I saw that the texts recognized but in one device it works and in other device does not.
What should I do?
For example, in one device, isOperational() returns false, and it goes to readstate() and after that goes to looper() and stays on it!
in other device it only return false and doesn't go to looper.
I want ask other questions about it:
My first question is: how does isOperational() work? I can't understand it.
Maybe it goes to looper to download the native library in a queue and after many try, at last download completes and work. Can it be correct? Or is it just a bug that it goes to looper? Anywhere, what should I do?
Can I work on this when it works in one device I tried and in other does not? Or it must work in every device to I can work on it? And I get .apk from project but it can't install in devices, why?
Should it check for network?
Should it check for access to the memory?
note: it works with camera API and its deprecated. maybe the problem is with this!
TextRecognizer textRecognizer = new TextRecognizer.Builder(context).build();
textRecognizer.setProcessor(new OcrDetectorProcessor(graphicOverlay));
if (!textRecognizer.**isOperational**()) {
// Note: The first time that an app using a Vision API is installed on a
// device, GMS will download a native libraries to the device in order to do detection.
// Usually this completes before the app is run for the first time. But if that
// download has not yet completed, then the above call will not detect any text,
// barcodes, or faces.
//
// isOperational() can be used to check if the required native libraries are currently
// available. The detectors will automatically become operational once the library
// downloads complete on device.
Log.w(TAG, "Detector dependencies are not yet available.");
// Check for low storage. If there is low storage, the native library will not be
// downloaded, so detection will not become operational.*
IntentFilter lowstorageFilter = new IntentFilter(Intent.ACTION_DEVICE_STORAGE_LOW);
boolean hasLowStorage = registerReceiver(null, lowstorageFilter) != null;
if (hasLowStorage) {
Toast.makeText(this, R.string.low_storage_error, Toast.LENGTH_LONG).show();
Log.w(TAG, getString(R.string.low_storage_error));
}
}
*// Creates and starts the camera. Note that this uses a higher resolution in comparison
// to other detection examples to enable the text recognizer to detect small pieces of text.*
cameraSource =
new CameraSource.Builder(getApplicationContext(), textRecognizer)
.setFacing(CameraSource.CAMERA_FACING_BACK)
.setRequestedPreviewSize(1280, 1024)
.setRequestedFps(2.0f)
.setFlashMode(useFlash ? Camera.Parameters.FLASH_MODE_TORCH : null)
.setFocusMode(autoFocus ? Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO : null)
.build();
}
It doesn't produce any error and show preview camera but doesn't recognize texts in some devices.
I'd like to disable some features and reduce memory consumption on Android Go Devices. I'd like to have one APK for all Android devices.
How do I detect that my app is running on an Android Go 8.1 Device?
Is it sufficient to check for version 8.1 or will 8.1 version be distributed to normal Android Devices as well?
This works for me, based on preinstalled Apps.
If Assistant Go or Google Go versions are installed, definitely is an Android Go device.
In rare cases that these apps didn't come preinstalled we look for Gmail Go and also Youtube Go preinstalled.
Tested on Huawei Y5 Lite with Android 8.1 (Go).
public static boolean isAndroidGoEdition(Context context) {
final String GMAIL_GO = "com.google.android.gm.lite";
final String YOUTUBE_GO = "com.google.android.apps.youtube.mango";
final String GOOGLE_GO = "com.google.android.apps.searchlite";
final String ASSISTANT_GO = "com.google.android.apps.assistant";
boolean isGmailGoPreInstalled = isPreInstalledApp(context, GMAIL_GO);
boolean isYoutubeGoPreInstalled = isPreInstalledApp(context, YOUTUBE_GO);
boolean isGoogleGoPreInstalled = isPreInstalledApp(context, GOOGLE_GO);
boolean isAssistantGoPreInstalled = isPreInstalledApp(context, ASSISTANT_GO);
if(isGoogleGoPreInstalled | isAssistantGoPreInstalled){
return true;
}
if(isGmailGoPreInstalled && isYoutubeGoPreInstalled){
return true;
}
return false;
}
private static boolean isPreInstalledApp(Context context, String packageName){
try {
PackageManager pacMan = context.getPackageManager();
PackageInfo packageInfo = pacMan.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES);
if(packageInfo != null){
//Check if comes with the image OS
int mask = ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
return (packageInfo.applicationInfo.flags & mask) != 0;
}
} catch (PackageManager.NameNotFoundException e) {
//The app isn't installed
}
return false;
}
There doesn't seems to be direct api for retrieving whether app is running on GO version.
But you may cover the case by combination of following :
based on device memory and deciding on threshold value for your app:
private ActivityManager.MemoryInfo getAvailableMemory() {
ActivityManager activityManager =
(ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
ActivityManager.MemoryInfo memoryInfo = new
ActivityManager.MemoryInfo();
activityManager.getMemoryInfo(memoryInfo);
return memoryInfo;
}
Further similar steps can be take for particular model/manufacturer :
String deviceName = android.os.Build.MODEL;
String deviceMan = android.os.Build.MANUFACTURER;
Hope it helps.
No, as #chrylis pointed out, checking the version number wont help because there is a full Android version with the same number.
According to the documentation, to check whether the device is running Android Go you could call either
ActivityManager.isLowRamDevice();
or
PackageManager.hasSystemFeature("FEATURE_RAM_LOW");
Both will return true if the device is running Android Go edition, and false if it's running the regular Android.
I would rely on these APIs rather than checking for other Android Go edition system apps (like the android Go version of Gmail) because those apps may have been installed or uninstalled by the user, potentially triggering false positives or false negatives.
In my experience, is ActivityManager.isLowRamDevice() is equivalent to being an Android Go phone.
boolean isAndroidGo() {
return ((ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE))
.isLowRamDevice();
}
}
Although, the last time I looked in the documentation, I don't think it says anywhere, explicitly, that Android Go and isLowRamDevice() are equivalent.
I am setting up the Android Device Buttons to work with my app. According to the PG/Cordova documentation I should be able to just add an listener such as
document.addEventListener("backbutton", function() {
console.log('Back Button Pressed.');
}, false);
However, when using my Nexus 7 as a test device, nothing happens.
I have also tried adding the override directly into Java:
#Override
public void onBackPressed() {
super.loadUrl("javascript:onBackKeyDown()");
return;
}
But once again, seems to do nothing. Anyone else having this issue or fixed?
Thank you.
First of all, ur function write into the console.
document.addEventListener("backbutton", function() {
console.log('Back Button Pressed.');
}, false);
You should set your device as debugging tools (, you will find below a quick hint how to do it, for more info go here )
Connect your phone to the pc
On your phone: check USB debugging;
setting => Developer Option => USB debugging
On your phone: check unknown sources;
settings >> applications >> unknown sources = true
add your device to the ADT (in your SDK)
run the project directly from the pc to the mobile :
right-click on the project => Run AS => choose your device
NOW on Back button Click, "Back Button Pressed." will be printed in the console of Eclipse.
If your device is not connected to the Computer or if your device is not set as debugging tools, Nothing will change.
In General case Use "alert()" in stead of "console.log()" if you are testing on the device without setting it as debugging tools.
Beside, dont use the native java, use the original documentation of Cordova, just add the following code into your javascript files:
function onLoad() {
document.addEventListener("deviceready", onDeviceReady, false);
}
// Cordova is loaded and it is now safe to call Cordova methods
//
function onDeviceReady() {
// Register the event listener
document.addEventListener("backbutton", onBackKeyDown, false);
}
// Handle the back button
//
function onBackKeyDown() {
// whatever you want to do
alert('Back button Pressed');
}
then you should add "onLoad()" to the body tag:
<body onLoad="onLoad()">
I would like to ascertain at run-time inside an Android app whether it is running within the BlueStacks Android emulator. This is so I can modify the way the app runs when running inside BlueStacks.
BlueStacks does not support multi-touch so I want to implement an alternative to the standard pinch-to-zoom functionality my current app has.
E.g.
If (appIsRunningInBlueStacks){
mySurfaceView.enableMultiTouchAlternatives();
} else{
mySurfaceView.enableMultiTouchFeatures();
}
What is a reliable way of ascertaining the value of appIsRunningInBlueStacks?
EDIT Summary of answers to comments on question:
Ben, Taras, thanks for the suggestions. The Build.MODEL etc. values for BlueStacks are:
Model: "GT-I9100"
Manufacturer: "samsung"
Device: "GT-I9100"
Product: "GT-I9100"
This is the same model number as the Samsung Galaxy SII so it would not be ideal to use this for fear of treating all users with SIIs the same as those on BlueStacks.
CommonsWare, the app continues to run in BlueStacks even with the < uses-feature> for multitouch in the manifest. In fact (also answering iagreen's question)...
packageManager.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT);
... returns true! This is to be expected I suppose as the emulator is convinced it is a Samsung Galaxy SII!
Therefore we are still without a way of reliably detecting whether an app is running on BlueStacks without also throwing all Samsung Galaxy SII users in the same bucket. Any other ideas?
All the above methods are not working on BlueStacks 5. The correct way to do is checking if the path of /mnt/windows/BstSharedFolder exists. It is working fine on both BlueStacks 4 and 5.
fun checkFilesExist(files: Array<String>): Boolean {
files.forEach {
val file = File(it)
if (file.exists()) {
return true
}
}
return false
}
fun isBlueStacks(): Boolean {
val BLUE_STACKS_FILES = arrayOf(
"/mnt/windows/BstSharedFolder"
)
return checkFilesExist(BLUE_STACKS_FILES)
}
You can check that the Bluestacks shared folder exist
/sdcard/windows/BstSharedFolder
Boolean onBlueStacks()
{
File sharedFolder = new File(Environment
.getExternalStorageDirectory().toString()
+ File.separatorChar
+ "windows"
+ File.separatorChar
+ "BstSharedFolder");
if (sharedFolder.exists())
{
return true;
}
return false;
}
After trying all the suggested solutions available online we found the Google's SafetyNet Attestation API is the only solution for detecting VMs like BlueStack(any version) and NoxPlayer.
Apps that care about content piracy (and other security issues) can filter their availability on the Google Play like Netflix filters devices on the PlayStore.
The new “device catalog” section of the console includes an option
called “SafetyNet exclusion,” which can be used to prevent “devices
that fail integrity tests or those that are uncertified by Google,”
from downloading a specific app: among these would be rooted devices
and those running custom ROMs.
But there is a catch user will still find the APK from cross-sharing or other distribution systems, so the client must implement SafetyNet Attestation API on the app level.
How does it work?
SafetyNet examines software and hardware information on the device
where your app is installed to create a profile of that device. The
service then attempts to find this same profile within a list of
device models that have passed Android compatibility testing. The API
also uses this software and hardware information to help you assess
the basic integrity of the device, as well as the APK information of
the calling app. This attestation helps you to determine whether or
not the particular device has been tampered with or otherwise
modified.
It's an (easy to implement) paid API from the Google which allows 10,000 free hits per day as of now :\
If anyone is interested in detecting VMs by them self, these are the good papers available suggesting heuristic approaches :
Evading Android Runtime Analysis via Sandbox Detection
Rage Against the Virtual Machine:
Hindering Dynamic Analysis of Android Malware
My version of BlueStacks is reporting my Build.Model as GT-N7100.
Using: android.opengl.GLES20.glGetString(android.opengl.GLES20.GL_RENDERER) I get Bluestacks.
It maybe too late but for the sake of others who have the same problem :
public boolean isRunningOnEmulator() {
return Build.FINGERPRINT.startsWith("generic")
|| Build.FINGERPRINT.startsWith("unknown")
|| Build.MODEL.contains("google_sdk")
|| Build.MODEL.contains("Emulator")
|| Build.MODEL.contains("Android SDK built for x86")
|| Build.MANUFACTURER.contains("Genymotion")
|| (Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic"))
|| "google_sdk".equals(Build.PRODUCT)
|| Build.PRODUCT.contains("vbox86p")
|| Build.DEVICE.contains("vbox86p")
|| Build.HARDWARE.contains("vbox86");
}
Based on Mr. Regis' answer, you can detect it when the shared folder is present. However in Bluestacks 4, using file.exists() will only return false. This is because the shared folder has no permissions (000 or ----------). But listing files in the directory will detect the folder.
String path = Environment.getExternalStorageDirectory().toString();
Log.d("FILES", "Path: " + path);
File directory = new File(path);
File[] files = directory.listFiles();
for (File file : files) {
if (file.getName().contains("windows")) {
Log.d("FILES", "windows file exists, it's a bluestacks emu");
}
}
This Will be unique.
There is no bluetooth device in Bluestack.
So try to get The Bluetooth Address string which is always 'null' on Bluestack or Any emulator.Make sure you are adding Bluetooth permission on your project manifest.
BluetoothAdapter m_BluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
String m_bluetoothAdd = m_BluetoothAdapter.getAddress();