I have a smartwatch 2 app on the market which has been working fine for months, but recently it has started crashing a second after the context menu is opened.
The onKey code looks like this:
#Override
public void onKey(final int action, final int keyCode, final long timeStamp) {
// Menu button click
if (action == Control.Intents.KEY_ACTION_RELEASE
&& keyCode == Control.KeyCodes.KEYCODE_OPTIONS) {
showMenu(mMenuItemsText);
}
}
(mMenuItemsText is defined at the class level and instantiated in the constructor:
mMenuItemsText[0] = new Bundle();
mMenuItemsText[0].putInt(Control.Intents.EXTRA_MENU_ITEM_ID, MENU_ITEM_REVERSE_RATE);
mMenuItemsText[0].putString(Control.Intents.EXTRA_MENU_ITEM_TEXT, context.getResources().getString(R.string.converter_menu_reverse_rate));
)
When I click the watch menu button in my app, the menu opens up, and then a second later the watch crashes and disconnects from the phone before starting back up and reconnecting to the phone. Nothing in logcat and the phone doesn't show a crash prompt, it seems completely unaware that the watch has crashed.
If I put Log.d statements on each line above then they all show up in logcat, it seems to be happening after the menu has finished its "swipe in" animation.
Thinking the problem was in the utils app, I tried replacing the showMenu call with the same code to send the menu intent directly:
#Override
public void onKey(final int action, final int keyCode, final long timeStamp) {
// Menu button click
if (action == Control.Intents.KEY_ACTION_RELEASE
&& keyCode == Control.KeyCodes.KEYCODE_OPTIONS) {
Intent intent = new Intent(Control.Intents.CONTROL_MENU_SHOW);
intent.putExtra(Control.Intents.EXTRA_MENU_ITEMS, mMenuItemsText);
sendToHostApp(intent);
}
}
But I get the same problem. I have another SW2 app on the market with the same code and it works fine. I'm completely stumped as to how to find the problem, as I'm unable to step into the code in Eclipse.
This issue will be fixed in the upcoming 1.4.54 host app SW to be released in the next few days. The issue has to do with the number of touch regions supported, which has been increased from 25 to 30 in the update.
I have about the same problem. I have several menus in my app but only one of them will crash the Smartwatch 2. It happens every time now, also reported by many users. The problem came after the recent firmware update. So hopefully it will be fixed in a new firmware or updated SDK release.
My problem is now fixed in latest firmware from Sony
Related
I'm trying to develop an android app for the SDK version 30 that (when a button is clicked) starts listening to what apps are opened on the phone. If it detects the user opening Whatsapp, it is supposed to show a LockScreen activity over Whatsapp that makes you answer a math question before being able to use Whatsapp.
I know this can be done as their are apps like QualityTime or Forest that have similar features to restrict you from using certain apps, but I am a newbie when it comes to programming (probably obvious from my code) and feel totally stuck.
I have already figured out how to detect what app the user opened in the last second with code from stack overflow:
public String getCurrentApp() {
String topPackageName = "None";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
UsageStatsManager mUsageStatsManager = (UsageStatsManager) getSystemService("usagestats");
long time = System.currentTimeMillis();
List<UsageStats> stats = mUsageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - 1000 * 1, time);
// Sort the stats by the last time used
if (stats != null) {
SortedMap<Long, UsageStats> mySortedMap = new TreeMap<Long, UsageStats>();
for (UsageStats usageStats : stats) {
mySortedMap.put(usageStats.getLastTimeUsed(), usageStats);
}
if (!mySortedMap.isEmpty())
{
topPackageName = mySortedMap.get(mySortedMap.lastKey()).getPackageName();
}
}
}
return topPackageName;
}
I have another function that is started when the user clicks the button in my app to "activate" the listening process. This function keeps checking if the user opens Whatsapp and is then supposed to display the Lockscreen activity on top:
public void startListening(View view)
{
System.out.println("Lock activated.");
while (activated) {
String currentlyRunningApp;
currentlyRunningApp = getCurrentApp();
if (currentlyRunningApp.equals("com.whatsapp"))
{
System.out.println("Whatsapp detected. Showing Lockscreen...");
Intent i = new Intent(this,LockScreen.class);
startActivity(i);
}
try {
Thread.sleep(800);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
(All of the code I have shown is in my MainActivity btw.)
I have the following permissions granted to my app:
android.permission.PACKAGE_USAGE_STATS (for the getCurrentApp() function)
android.permission.SYSTEM_ALERT_WINDOW (as suggested here)
android.permission.ACTION_MANAGE_OVERLAY_PERMISSION (although I am not sure I even need this one)
My problem is, that instead of showing the Lockscreen activity I created, it only shows a blackscreen for the user. The Lockscreen activity itself works fine if I let the user open it through a button on the mainActivity, so the issue seems to really be that I can not properly show an activity if my app is running in the background and I want to display it on top of Whatsapp.
I have tried to look through similar questions, but all of the posts on here with similar use cases seem to be very old and outdated (i.e. this or this), as the newer versions seem to have way tighter security restrictions.
I also tried to do it with a screen overlay instead of an activity (using this source), but this doesn't even give me a blackscreen - just does nothing...
I am also aware that there are probably better ways to program the whole "listening and checking for whatsapp" part - i.e. with a service instead of a while-loop or something, but I only found out about services while researching this problem and I'd like to fix the blackscreen issue first.
After lots of trial and error I figured out that the issues was indeed caused by a missing permission, but one that I could not find on any stack overflow answer related to black screen problems. On top of that, I believe it's an issue that only occurred because I used a Xiaomi device for testing.
There are currently two separate permissions for displaying screens over other apps that you will need to grant:
Display over other apps, also called Display pop-up window. This is the android.permission.ACTION_MANAGE_OVERLAY_PERMISSION that I wasn't sure was even needed. So to emphasize, I definetly do need this permission.
Display pop-up windows while running in the background. This is the permission I was missing.
After I allowed them both (which you can do under Settings > Apps > Manage Apps > Your App > Other Permissions) everything worked fine.
To direct the user directly to the settings menu where they can allow these permissions, I used the code from this stack overflow answer. This is also where I got the info that it's a xiaomi-specific "issue".
How can I go to recent apps menu and How to select a particular app from the recents by using Espresso Android Instrumentation Test
Since selecting app from recent apps menu, it need controller over device. I think it can't be done with Espresso alone.
But you can achieve this by using android uiautomator.
fun selectAppFromRecentApps(appTitle:String){
mDevice.pressHome()
mDevice.pressRecentApps()
var uiSelector = UiSelector().className("android.widget.ScrollView") //scroll view listing all recent apps
var count = mDevice.findObject(uiSelector).childCount
for (i in 0 until count step 1) {
val child = UiScrollable(uiSelector.childSelector(UiSelector().resourceId("com.android.systemui:id/task_view_bar").instance(i))).getChild(UiSelector().resourceId("com.android.systemui:id/title")) // app framelayout
val text = child.text
if (text == appTitle) {
child.click()
break
}
if(i==count-1){
throw RuntimeException("App : "+ appTitle +" not found in
recent apps")
}
}
}
Unfortunately VIGNESHs answer did not work for me. I expect different devices to have different implementations of the overview view, or probably it's the Android version.
Anyway the following worked for me on different devices:
getInstrumentation().waitForIdleSync();
mDevice.pressHome();
mDevice.pressRecentApps();
mDevice.waitForIdle();
// If the application is listed, there needs to be an element with a content description
// containing the package name
if (!mDevice.wait(Until.hasObject(By.descStartsWith(getTargetContext().getPackageName())), 1000))
{
fail("Overview did not open");
}
// As the app to be tested was the last one opened, we can simply press the button again.
mDevice.pressRecentApps();
// Wait until the activity under test is back.
// If you skip that, you might be to early, doing further tests.
mDevice.wait(Until.hasObject(By.pkg(getTargetContext().getPackageName())), 1000);
getInstrumentation().waitForIdleSync();
I'm facing a rather odd problem, I'm using unity 2017.3.1f1 Personal.
When I build the APK and I copy that file to the phone and install it from the phone's file manager, I can't switch from the main menu to the first scene, the game crashes at the load scene or just freezes after selection, thought it was due to the Async code so I tried without it and have no result at all.
When I select Build and Run this doesn't happen at all and the application runs normally, what I'm I missing here or how can I fix this? Already restarted unity and the computer many times.
Here's the code I'm using to switch in between scenes including the code without the Async mode:
public void Car1()
{
selectedCar = 0;
canvasManagerGO.GetComponent<CanvasManager>().Close();
SceneManager.LoadScene("W" + selectedWorld + "-L1", LoadSceneMode.Single);
}
public void Car2()
{
selectedCar = 1;
canvasManagerGO.GetComponent<CanvasManager>().Close();
SceneManager.LoadScene(1, LoadSceneMode.Single);
}
public void Car3()
{
selectedCar = 2;
canvasManagerGO.GetComponent<CanvasManager>().Close();
StartCoroutine(ChangeScene("W" + selectedWorld + "-L1"));
public IEnumerator ChangeScene(string sceneName)
{
loadingCanvas.SetActive(true);
AsyncOperation asyncOperation = SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Single);
while (!asyncOperation.isDone)
{
float progress = Mathf.Clamp01(asyncOperation.progress / .9f);
//Debug.Log(asyncOperation.progress);
slider.value = progress;
yield return null;
}
yield return null;
}
Car 1 and 2 have a direct mode without using the coroutine to change the scene and none of them work, the code has no errors at all or at least the console is not reporting anything, I also tried with different build settings and compressions, also with or without development build to check the profiler and nothing, thanks you all :)
I ran the ADB debugger and found nothing, the app just shows a blank line and that's it goes dead, I even put Lunar console on my project and it was a great help to see errors unity doesn't show but was not of much help either.
The solution I found was at this video https://www.youtube.com/watch?v=OxLa2uPW0dI
I followed the exact settings for "player settings -> other settings" he used and apparently it solved the problem at least for now but can't point at which setting was causing this behaviour
I have an Android application for a Samsung tablet that uses an external device which draws its power from the tablet headphone jack. When the external device is powered on (by programmatically maxing out the volume), Android briefly displays a warning popup saying: "Loud music may harm your hearing if you listen to it for too long..." I would like that message to not be displayed.
Here's the offending line of code:
mAudioMgr.setStreamVolume(AudioManager.STREAM_MUSIC, mAudioMgr.getStreamMaxVolume(AudioManager.STREAM_MUSIC), 0);
It's not an option to only turn it up halfway. In fact, I've seen the tablet display the warning (when changing the volume by hand) even on volume settings lower than the max setting.
And yes, I record the original volume, and restore it when we're done with the external device.
Thanks for any suggestions.
Since you cannot disable the systems message, and you will also have a problem when the user manually lowers the volume, I suggest you do a series of controls which will help with that.
To max the volume:
public void maxVolume() {
AudioManager audioManager = (AudioManager)context.getSystemService(this.AUDIO_SERVICE);
while ( audioManager.getStreamVolume(AudioManager.STREAM_MUSIC) < audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)) {
audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_RAISE, 0);
}
}
To prevent users from manually changing volume:
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_VOLUME_DOWN)
|| (keyCode == KeyEvent.KEYCODE_VOLUME_UP)
|| (keyCode == KeyEvent.KEYCODE_VOLUME_MUTE)) {
return true;
}
return super.onKeyDown(keyCode, event);
}
You can call maxVolume() in your onCreate method, and later call it just before you start using the jack output procedure to make sure the system has not changed your volume.
Alternatively you can register a listener to listen for volume changes, make maxVolume() static and call it from the listener. Hope it helps you out!
I know that this question is quite old, but I just ran across this issue myself. I figured that I would add to the answers given with what I found in case it helps someone else that happens upon this.
One of the posts here mentions that the warning is not in the AOSP, but this is not true. Please reference the VolumePanel::SafteyWarning class here: VolumePanel::SafetyWarning
Once you peruse through the SafetyWarning class you'll notice that there is a hidden method inside of the AudioManager class called disableSafeMediaVolume. You can, through reflection, invoke this hidden method easily enough, but if you do then you'll get a security exception as it requires the system permission "android.permission.STATUS_BAR_SERVICE".
So... with that said, the dialog as far as I can tell, cannot be programmatically suppressed unless you have this system permission.
What we ended up doing with the blessing of product management is we cache the volume setting in SharedPreferences and then reset it from the cache when our application starts. If it happens to be above the threshold for the warning dialog then the warning will be shown and the user will just have to press OK to get the volume setting that they want, but at least they won't have to manually reset the volume themselves.
A couple of other notes on why some don't see this dialog. You will only see it if you have headphones (or earbuds, or a wired headset) plugged into the device and you attempt to set the media volume stream over a certain threshold (on the Samsung Galaxy Tab A this threshold is 60%). If you press OK at the dialog then it will not be shown again unless you either restart the device or unplug the headphones and plug them back in (with the volume set at or above the threshold).
Hope this helps someone.
I don't know if you can consider this much of an answer but I'm pretty sure you can't remove that message as its displayed by the system automatically and not by something you can access. My Samsung Galaxy S3 does the same thing.
Also from what I can read on the net some android devices also lower the volume when you put in a jack stick so "you don't harm your hearing".
Can you override the notification by displaying your own notification just before or after perhaps? The notification is just a standard Toast.
I have been trying to get a bitmap screenshot of a SurfaceView for days but the more I look into it, there doesn't seem to be a solution at present for Android OS 2.3.4 based OSs my device from HTC.
So on to Plan B, where I just found out another blog: "On my HTC Evo 3d, all I have to do is hold the power button for 1-2 sec and then hit the home button and it takes a screen shot. No app required." Turns out this works perfectly on my tablet.
I also know from digging around there are these intents: android.intent.action.SCREEN_OFF & android.intent.category.HOME
(So I tried a bunch of code experiments to try to mimic the 2-key combo in code to get a screenshot in this brute force manor. Unfortunately without success).
So my ? -- Does anyone have any insights into a method to invoke this 'screenshot sequence' for my HTC device from java code? (Presume I need to fool the OS into thinking I am holding down the power key AND tap the Home key, simultaneously)...
More: Here is a snip of the code I am attempting:
Button click for test... ...
Thread t = new Thread() {
public void run() {
Instrumentation inst = new Instrumentation();
inst.sendKeyDownUpSync(KeyEvent.KEYCODE_POWER);
Instrumentation inst2 = new Instrumentation();
inst2.sendKeyDownUpSync(KeyEvent.KEYCODE_HOME);
} // run
}; // thread t
Doesnt work as the inst.sendKeyDownUpSync is wrong as I need a sendKeyDown (& hold) behavior or its equivel
Many thanks for any advise. If I do get this working, I will post the solution here. Cheers GH
PS; I presume there is some custom intent under the hood doing this? Is there a system log somewhere to trey to peek at the call tree to find out what it is ?
EDIT (MORE)... 9/24/11
More. Still not working but I am heading down this path & think it is closer...
// Attempt to SIMULATE A Long press (DOWN) + HOME to tell the HTC to invoke the 'Screenshot' command (WARNING: HTC Tablet specific behavior!)
Thread tt = new Thread() {
public void run() {
final KeyEvent dapowerkey = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_POWER);
Handler onesecondhandler = new Handler();
onesecondhandler.postDelayed(new Runnable() {
public void run() {
// fpr about 1 second send power down keystrokes (DOWN ONLY)
while (true) { dispatchKeyEvent(dapowerkey); }
} // we are done running on the timer past time point
}, 750); // 3/4 second key press
// send the HOME keystroke
Instrumentation inst1 = new Instrumentation();
inst1.sendKeyDownUpSync(KeyEvent.KEYCODE_HOME);
} // outer thread run tp mpt block the GUI
}; // outer thread t
tt.start();
...
Also thought if I can send the right intent directly to the proper place on the device that I might be able to kick off a screen capture function directly (which is what I really want. Through some log examinations (when you Long-Power + Home click on HTC) a program called 'com.htc.mysketcher' (FlashActivity) is being called...
Again, if I figure this out then I will post to the group... Cheers GH