how to know which screen is open in blackberry? - java

how to know which screen is open/ in foreground in blackberry? In other words, can we get a name of the screen which is currently open in BB. It can include other app, call logs, messages etc. , not necessarily my APP. Can this be done? Thanks..

There are three methods in ApplicationDescriptor that can help you figure out the currently foregrounded app. Getting to the Application object itself may be a little more difficult, but you can at least discover the ApplicationDescriptor.
ApplicationManager mgr = ApplicationManager.getApplicationManager();
final ApplicationDescriptor[] vApps = mgr.getVisibleApplications();
int foregroundId = mgr.getForegroundProcessId();
for(int i = 0; i < vApps.length; i++) {
int id = mgr.getProcessId(vApps[i]);
if(id == foregroundId) {
// we have a winner!
}
}

Hopefully this is what you mean:
if (Application.getApplication().isForeground()) {
Screen scr = UiApplication.getUiApplication().getActiveScreen()​;
}

Related

How to force something to happen before something else JAVA

In my app I'm trying to create a "loading screen" so the user knows what's happening and doesn't think the app is lagging when loading a new view upon releasing a button. I'm trying to have my "setViewVisibility" method run before the rest of the code but I can't seem to make it work. The way I have it set up right now is that there's an instance boolean that gets changed when one action is completed but for some reason it's not working. Any ideas on how I could fix this?
if(isLoadScreen == true){
setViewVisibility(visibility.END);
buttoni.setAlpha((float) 1);
isLoadScreen = false;
}
if (isLoadScreen == false){
setKeysList(list);
startQuestion(keysList.get(0));
currentQuestion = 0;
isLoadScreen = true;
}
Your second block is always executed because isLoadScreen is always false at that point. You need to use else instead of if to get the behavior you want.
if (isLoadScreen == false){ //isLoadScreen is always false here - just use else instead
setKeysList(list);
startQuestion(keysList.get(0));
currentQuestion = 0;
isLoadScreen = true;
}
That said, there are better ways to create splash/loading screens - this question How do I make a splash screen? might provide some hints.

weird phenomenon about android Debugger (CloseableReference)

There I have a loop:
public void updateDrawee(View view) {
if (begin) {
begin = false;
for (int i = 0; i < 5; i++) {
CloseableReference<CloseableImage> reference = createBitmapRefer(i);
Log.i("reference", reference+"");
imgList.add(reference);
}Log.i("imgList", imgList.toString());Log.i("imgList.0", imgList.get(0)+"");
}
//...some code
}
and the method createBitmapRefer(int count) follow:
public CloseableReference<CloseableImage> createBitmapRefer(int count) {
ImagePipeline pipeline = Fresco.getImagePipeline();
int[] drawableIds = {R.drawable.alpha1, R.drawable.alpha2,
R.drawable.alpha3, R.drawable.alpha4, R.drawable.alpha5};
ImageRequest levelRequest
= ImageRequestBuilder.newBuilderWithResourceId(drawableIds[count])//++
.setProgressiveRenderingEnabled(true)//逐行加载
.build();
CloseableReference<CloseableImage> bmpReference = null;
DataSource<CloseableReference<CloseableImage>> dataSource
= pipeline.fetchImageFromBitmapCache(levelRequest, this);
try {
if (!dataSource.hasResult()) {
dataSource = pipeline.fetchDecodedImage(levelRequest, this);
}
//count %= 5;
Log.i("dataSource has result", dataSource.hasResult() +"");
Log.i("dataSource fail?", dataSource.hasFailed() + "");
bmpReference = dataSource.getResult();
Log.i("bmpRefer", bmpReference+"");
if (bmpReference != null) {
CloseableReference<CloseableImage> returnRef;
returnRef = bmpReference.clone();
return returnRef;
}else {
return null;
}
}finally {
dataSource.close();
CloseableReference.closeSafely(bmpReference);
}
}
when I debug, if i click step into and see the code step by step, it will return a CloseableReference just as I want, and the imgList(its a ArrayList) can get the element too.BUT if I step over the for loop, it return nothing!
Is there any different between keep looking at it or not???
the watches show elements in imgList, when index=1 and 4, I clicked step into.
and the logcat show what Log.i() print.
Or because I have not use this classCloseableReference in Standardized way?
Let me try to explain what happens here.
You are not using Fresco in the intended way. I will step back for a moment and strongly suggest that you use SimpleDraweView if you just need to display images. If however you really need the underlying bitmap, you can get it from the ImagePipeline in way similar to what you already doing, but with one key difference. Fetching images happens asynchronously. What that means is that you can't just do dataSource = pipeline.fetchDecodedImage(...) and then immediately dataSource.getResult. If the image was not found in the memory cache, getResult will just return null. What you need to do instead is to subscribe to the DataSource as explained in the Fresco documentation. I strongly suggest that you read those few chapters about ImagePipeline if you intend to use it directly. Otherwise you may cause your app to leak the memory or to crash because of rendering recycled bitmap.
What you see in debugger is exactly what I described above. The array of size 5 looks like this:
0 = null,
1 = CloseableReference#4908,
2 = null,
3 = null,
4 = CloseableReference#5231
The AndroidStudio UI just hides the null entries for brevity. You can turn this off if you don't like it by right-clicking there and opening options. The reason you get something for 1 and 4 is because the image has been found in the bitmap memory cache and was retrieved from it immediately. The reason you get null for 0, 2 and 3 is because the image has not been loaded yet. Fresco might need to download the image, and even if it is already downloaded and in the disk cache, it may need to decode the image. All of this takes some time and is not instantaneous. That's why you need to subscribe your callback and ImagePipeline will notify you when the image is ready.

Android - Getting return value of a thread

I start with Android and Java, and my English is not very good (sorry).
I'm doing a application which compare 2 pictures taking by the camera and return a float value = a ratio of identical pixels in the 2 pictures.
public static float comparePic(String img_1, String img_2){
Bitmap bitmap1 = BitmapFactory.decodeFile(img_1);
Bitmap bitmap2 = BitmapFactory.decodeFile(img_2);
int equ = 0;
//get one height and one width because we assume that pictures have always same sizes
int h = bitmap1.getHeight();
int w = bitmap1.getWidth();
for(int y=0;y<h;y++){
for (int x=0;x<w;x++){
int pixel1 = bitmap1.getPixel(x,y);
int pixel2 = bitmap2.getPixel(x,y);
//alpha doesn't matter, they're jpg
int redValue1 = Color.red(pixel1);
int redValue2 = Color.red(pixel2);
int greenValue1 = Color.green(pixel1);
int greenValue2 = Color.green(pixel2);
int blueValue1 = Color.blue(pixel1);
int blueValue2 = Color.blue(pixel2);
if (redValue1==redValue2 && greenValue1==greenValue2 && blueValue1==blueValue2){
equ++;
}
}
}
return (float)equ/(h*w);
}
When I execute it, I have this message : "I/Choreographer﹕ Skipped 730 frames! The application may be doing too much work on its main thread."
So I tried to do it with a thread, but I'm always failing because I don't know how to return the value.
Futhermore, by skipping frames I guess, the ratio is not correct.
I know that it's an asynchonous work, so what can I do ?
Thanks !
You can simply add a public (setter-)method in your main class (or wherever you need the value).
When your async thread is done call the method with equ as the parameter.
You obviously need to care about thread-safety so consider making the method sychronized.
You should give a try to AsyncTask. It's a class specifically prepared for background processing. It has some drawbacks (it's not good idea to do networking with AsyncTask), but for some picture comparison stuff it is a great tool.
Define an Asynctask with a interface and implement that interface in the main Activity.
That way you can notify that host activity that the background asynctask has completed.

Barcode location while scanning

I'm using for my app the RedLaser library for barcode scanning (which is built off Zxing, I believe). Everything is working fine, while in scanning mode, any barcode that comes within view is scanned, but I don't want that, I want only barcodes that are aligned in a scanning area to be considered and the rest to be ignored.
The redlaser sample app, after which I implemented the library in my own app, had a rectangle on the layout of the scanning activiy, however that was ignored, as barcodes from any part of the screen were scanned and taken into account by the sample app.
Bottom line: I want my scanning activity to compare the location of the currently detected barcode and see if it is within the bounds of the "scanning area", if it is not then it won't be read.
Here is the code for the adjustment of the "scanning area":
viewfinderView = findViewById(R.id.view_finder);
LayoutParams params = new LayoutParams((int)(mDisplay.getWidth() * .75f),
(int)(mDisplay.getHeight() * .33f));
params.gravity = Gravity.CENTER;
viewfinderView.setLayoutParams(params);
The following code doesn't do anything, I just wrote it to exemplify the how everything works (since I don't have the source files for the Redlaser library), like the barcodelocation.
Set<BarcodeResult> allResults = (Set<BarcodeResult>) scanStatus.get(Status.STATUS_FOUND_BARCODES);
for( BarcodeResult s : allResults)
{
ArrayList<PointF> barcodelocation = s.barcodeLocation;
float x = barcodelocation.get(0).x;
float y = barcodelocation.get(0).y;
//there will be 4 points to each scanned barcode => 8 float's/barcode
}
Sorry for the long post, but I've been on this issue for a while now and I'm really stuck.
Any help is appreciated!
Managed to find a solution on the Redlaser site: turning the view into a rect then comparing the barcode location with that using .contain :
Rect scanningArea = new Rect(viewfinderView.getLeft(), viewfinderView.getTop(), viewfinderView.getRight(), viewfinderView.getBottom());
if(latestResult.iterator().hasNext())
{
boolean isInside = true;
ArrayList<PointF> barcodelocation = latestResult.iterator().next().barcodeLocation;
for (int i = 0; i < barcodelocation.size(); i++)
{
int x = (int) barcodelocation.get(i).x;
int y = (int) barcodelocation.get(i).y;
if (!scanningArea.contains(x, y))
{
isInside = false;
}
}
if (isInside)
{
//do stuff here
}
}
I'm still working on a few issues, but this question is answered now. Gonna go ahead and give myself a pat on the back. :)

Check for navigation bar

I am trying to check to see whether the android navigation bar is present on load so that I can adjust a layout accordingly, does anyone have any suggestions?
This is the navigation bar I am trying to detect:
P.S. All I have found so far are 'bad' ways to try and remove the bar, which I dont want to do.
Took me some time but I've found a more reliable way than relying on hasPermanentMenuKey() which doesn't work for newer phones like the HTC One which have no menu key but do have home & back keys so don't need (or show) the soft navigation bar. To get around this try the following code which checks for a back button too:
boolean hasMenuKey = ViewConfiguration.get(context).hasPermanentMenuKey();
boolean hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK);
if(!hasMenuKey && !hasBackKey) {
// Do whatever you need to do, this device has a navigation bar
}
There's no reliable way to check for a navigation bar. Using KeyCharacterMap.deviceHasKey you can check if certain physical keys are present on the device, but this information is not very useful since devices with physical keys can still have a navigation bar. Devices like the OnePlus One, or any device running a custom rom, have an option in the settings that disables the physical keys, and adds a navigation bar. There's no way to check if this option is enabled, and deviceHasKey still returns true for the keys that are disabled by this option.
This is the closest you can get:
boolean hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK);
boolean hasHomeKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_HOME);
if (hasBackKey && hasHomeKey) {
// no navigation bar, unless it is enabled in the settings
} else {
// 99% sure there's a navigation bar
}
If the back and home button are not both physically present on the device, it must have a navigation bar, because the user otherwise wouldn't be able to navigate at all. However, you can never be 100% sure about this, since manufacturers can implement deviceHasKey wrong.
Another solution
(a part of my class UtilsUISystem )
public static boolean hasNavBar (Resources resources)
{
//Emulator
if (Build.FINGERPRINT.startsWith("generic"))
return true;
int id = resources.getIdentifier("config_showNavigationBar", "bool", "android");
return id > 0 && resources.getBoolean(id);
}
Here is a quick answer that combines Pauland's and Philask's solutions. I'm afraid I don't have enough devices available to test if it works everywhere, though. I'd be interested to hear others' results.
boolean hasNavBar(Context context) {
Resources resources = context.getResources();
int id = resources.getIdentifier("config_showNavigationBar", "bool", "android");
if (id > 0) {
return resources.getBoolean(id);
} else { // Check for keys
boolean hasMenuKey = ViewConfiguration.get(context).hasPermanentMenuKey();
boolean hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK);
return !hasMenuKey && !hasBackKey;
}
}
I've done like this, it works on every device I tested, and even on emulators:
public static boolean hasNavigationBar(Activity activity) {
Rect rectangle = new Rect();
DisplayMetrics displayMetrics = new DisplayMetrics();
activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(rectangle);
activity.getWindowManager().getDefaultDisplay().getRealMetrics(displayMetrics);
return displayMetrics.heightPixels != (rectangle.top + rectangle.height());
}
you could add this code to your activity's onCreate() method:
View decorView = getWindow().getDecorView();
decorView.setOnSystemUiVisibilityChangeListener
(new View.OnSystemUiVisibilityChangeListener() {
#Override
public void onSystemUiVisibilityChange(int visibility) {
if ((visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0) {
// TODO: The navigation bar is visible. Make any desired
// adjustments to your UI, such as showing the action bar or
// other navigational controls.
} else {
// TODO: The navigation bar is NOT visible. Make any desired
// adjustments to your UI, such as hiding the action bar or
// other navigational controls.
}
}
});
This method worked for me
int id = getResources().getIdentifier("config_showNavigationBar","bool","android");
boolean result = id > 0 && getResources().getBoolean(id);
//
if(result) {
// Do whatever you need to do, this device has a soft Navigation Bar
}
It worked for me and tested in many devices.
Something that should probably work better is to measure the screen.
Starting with API 17 there's getWindowManager().getDefaultDisplay().getRealSize(), which can be compared to size returned by getWindowManager().getDefaultDisplay().getSize().
If you get different results I think it's safe to say that there is a nav bar and if you get the same results there isn't one. One thing to pay attention to is your target SDK and supported screens, which might cause the result of getSize() to be scaled if Android thinks your app wouldn't work well on the current device without scaling.
Below API 17 you can measure the screen via getWindowManager().getDefaultDisplay().getMetrics() in both landscape and portrait mode, and again, different results probably mean there's a nav bar.
However, if you get the same results, you don't actually know, as phones can keep the nav bar on the shorter edge even when in landscape. An educated guess would be that if either the width or the height is 4% to 8% smaller than standard sizes like 1280x800, 1280x720, 1024x600, while the other dimension is equal, then again there probably is a nav bar. Don't bet on it, though. There are too many resolutions, which differ too little from one another for this to work well.
boolean hasNavBar(Context context) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
// navigation bar was introduced in Android 4.0 (API level 14)
Resources resources = context.getResources();
int id = resources.getIdentifier("config_showNavigationBar", "bool", "android");
if (id > 0) {
return resources.getBoolean(id);
} else { // Check for keys
boolean hasMenuKey = ViewConfiguration.get(context).hasPermanentMenuKey();
boolean hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK);
return !hasMenuKey && !hasBackKey;
}
} else {
return false;
}
}
On Android 10 (API level 29), you can also check for the bottom window inset:
#RequiresApi(api = Build.VERSION_CODES.Q)
private boolean hasNavigationBar() {
final WindowInsets windowInsets = getWindow().getDecorView().getRootWindowInsets();
if (windowInsets == null) {
throw new RuntimeException("Window is not attached");
}
return windowInsets.getTappableElementInsets().bottom > 0;
}
Note that the window has to be attached for getRootWindowInsets() to return a non-null value, so you likely want to call this in onAttachedToWindow.
This solution is also used by LineageOS's launcher app Trebuchet (source), which is how I learned of it.
I see the answers above, I want to indicate
that the "not exist" can be regard as the height of 0;
so it can be like this:
public static int getScreenH(Context context) {
DisplayMetrics dm = new DisplayMetrics();
dm = context.getResources().getDisplayMetrics();
int h = dm.heightPixels;
return h;
}
public static int getDpi(Context context) {
DisplayMetrics displayMetrics1 = context.getResources().getDisplayMetrics();
int height1 = displayMetrics1.heightPixels;
int dpi = 0;
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = windowManager.getDefaultDisplay();
DisplayMetrics displayMetrics = new DisplayMetrics();
#SuppressWarnings("rawtypes")
Class c;
try {
c = Class.forName("android.view.Display");
#SuppressWarnings("unchecked")
Method method = c.getMethod("getRealMetrics", DisplayMetrics.class);
method.invoke(display, displayMetrics);
dpi = displayMetrics.heightPixels;
} catch (Exception e) {
e.printStackTrace();
}
return dpi;
}
public static int getBottomStatusHeight(Context context) {
int totalHeight = getDpi(context);
int contentHeight = getScreenH(context);
return totalHeight - contentHeight;
}
```
Solution: Only devices without permanent hardware keys have the navigation bar hence you can check for the API version and use hasPermanentMenuKey() to find hardware keys
boolean hasMenuKey = ViewConfiguration.get(context).hasPermanentMenuKey();

Categories

Resources