I'm trying to modify the MLSeries pose detection code by Google, when it reached 3 squats it will open a new activity. But, after I edit the code and ran it, it open the new activity multiple times. How I can avoid the app to open the activity multiple times when it reached certain reps?
// Update {#link RepetitionCounter}s if {#code isStreamMode}.
if (isStreamMode) {
// Feed pose to smoothing even if no pose found.
classification = emaSmoothing.getSmoothedResult(classification);
// Return early without updating repCounter if no pose found.
if (pose.getAllPoseLandmarks().isEmpty()) {
result.add(lastRepResult);
return result;
}
for (RepetitionCounter repCounter : repCounters) {
int repsBefore = repCounter.getNumRepeats();
repsAfter = repCounter.addClassificationResult(classification);
if (repsAfter > repsBefore) {
// Play a fun beep when rep counter updates.
ToneGenerator tg = new ToneGenerator(AudioManager.STREAM_NOTIFICATION, 100);
tg.startTone(ToneGenerator.TONE_PROP_BEEP);
lastRepResult = String.format(
Locale.US, "%s : %d reps", repCounter.getClassName(), repsAfter);
break;
}
if (repsAfter == 3){
//simpan nilai timer dekat sini dulu
swstopw2();
tmClass.stopTimer();
stopwatcher.swstop();
context.startActivity(intent);
}
}
result.add(lastRepResult);
}
Related
Just an example, I can get the Display Timeout setting like this:
int timeout = Settings.System.getInt(getContentResolver(), Settings.System.SCREEN_OFF_TIMEOUT);
I can set the Display Timeout setting like this:
Settings.System.putInt(getContentResolver(), Settings.System.SCREEN_OFF_TIMEOUT, 10000);
How can I programmatically get and set the Fast Charging and the Super Fast Charging settings?
Edit: Thanks to Veniamin for helping me get the correct variable names, here's what worked for me:
try {
int isSuperFastChargingEnabled = Settings.System.getInt(getContentResolver(), "super_fast_charging");
if ( isSuperFastChargingEnabled == 0) {
Settings.System.putInt(getContentResolver(), "super_fast_charging", 1);
Settings.System.putInt(getContentResolver(), "adaptive_fast_charging", 1);
Toast.makeText(this, "Fast charge is set to 1",Toast.LENGTH_LONG).show();
} else if ( isSuperFastChargingEnabled == 1) {
Settings.System.putInt(getContentResolver(), "super_fast_charging", 0);
Settings.System.putInt(getContentResolver(), "adaptive_fast_charging", 0);
Toast.makeText(this, "Fast charge is set to 0",Toast.LENGTH_LONG).show();
}
} catch (Settings.SettingNotFoundException e) {
Toast.makeText(this,"Failed to get fast charge setting",Toast.LENGTH_LONG).show();
}
You can read and update these settings in the Device Care Samsung system application, so I reverse engineered it.
Here is how you can read Fast Charging, Super Fast Charging, and Fast Wireless Charging settings in your application:
val isSuperFastChargingEnabled = Settings.System.getInt(context.contentResolver, "super_fast_charging", 0) == 1
val isFastChargingEnabled = Settings.System.getInt(context.contentResolver, "adaptive_fast_charging", 0) == 1
val isFastWirelessChargingEnabled = Settings.System.getInt(context.contentResolver, "wireless_fast_charging", 0) == 1
Unfortunately, to update these settings programmatically, you need the android.permission.WRITE_SETTINGS permission is only granted to the system applications.
So, if you are not developing a system app, the only way to enable these settings is to ask users to enable them manually. To simplify workflow, you can route users directly to the system Fast Charging Settings Activity, like so:
val intent = Intent()
intent.component = ComponentName(
"com.samsung.android.lool",
"com.samsung.android.sm.battery.ui.BatteryAdvancedMenuActivity"
)
// Activity class name may be updated in future versions, so
// the safest way to handle Activity class name updates is to wrap this
// call in the try/catch and add a custom error handling if the activity wasn't found.
try {
startActivity(intent)
} catch (e: Exception) {
// Custom error handling
}
Since these settings are vendor-specific, checking the vendor id before reading them is recommended.
I tested it and confirm that it works on the Samsung Galaxy S20 (SM-G980F/DS); Android 12; One UI 4.1.
I have a system that has been produced for 2 years now. It is an EMM system for controlling corporate devices.
It uses FireBase to send the functionality executed on the device from the server app to the device.
There are around 400 possible commands you can send to a device and all these commands are handled in one class initially, which overrides the onMessageReceived() from the FireBaseMessagingService class.
The older version of Android studio built the apk which is now in production. I have started to work on version 2 of my system after about a year off. so I updated my Android studio to the latest (4).
The Problem:
when I try to build the project and push onto a device, I get
error: code too large public void onMessageReceived(RemoteMessage remoteMessage) {
As stated before this onMessageReceived method can handle 400 different types of push notifications from the server app, so there are a lot of if/else statements in the method body.
Is there any reason why since the AS upgrade this will not work?
is there any setting I can change in AS to get past this?
What I have tried:
I thought about putting half of the if/else in another service class, to cut down on the method code. This would involve passing the remoteMessageMap to another class to carry on with the if/else processing.
remoteMessageMap from FireBase is a Map and Maps are not serializable as they extend the interface, so can't pass it.
public class MyAndroidFirebaseMsgService extends FirebaseMessagingService {
private static final String TAG = "MyAndroidFCMService";
AppObj appObj;
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.e(TAG, "remoteMessage.getData() = " + remoteMessage.getData());
Map remoteMessageMap = remoteMessage.getData();
String message = (String)remoteMessageMap.get("message");
thanks
[edit1]
else if(message.trim().equalsIgnoreCase("CLEARCACHE_REMOVE_APP_WL")){
Log.e(TAG, "received CLEARCACHE_REMOVE_APP_WL");
String pushGuid = (String)remoteMessageMap.get("pushguid");
Log.e(TAG, "pushGuid = " + pushGuid);
String clearCacheRemoveWhitelist = (String)remoteMessageMap.get("clear_cache_app_names");
Intent intentExecutePushCommand = new Intent( getApplicationContext(), ExecutePushCommandIntentService.class);
intentExecutePushCommand.putExtra("compID", MenuActivity.companyID);
intentExecutePushCommand.putExtra("command", message);
intentExecutePushCommand.putExtra("pushguid", pushGuid);
intentExecutePushCommand.putExtra("clear_cache_app_names", clearCacheRemoveWhitelist);
startService(intentExecutePushCommand);
}else if(message.trim().equalsIgnoreCase("CLEARCACHE_GET_PACKAGENAMES_WL")){
Log.e(TAG, "received CLEARCACHE_GET_PACKAGENAMES_WL");
String pushGuid = (String)remoteMessageMap.get("pushguid");
Log.e(TAG, "pushGuid = " + pushGuid);
Intent intentExecutePushCommand = new Intent( getApplicationContext(), ExecutePushCommandIntentService.class);
intentExecutePushCommand.putExtra("compID", MenuActivity.companyID);
intentExecutePushCommand.putExtra("command", message);
intentExecutePushCommand.putExtra("pushguid", pushGuid);
startService(intentExecutePushCommand);
}else if(message.trim().equalsIgnoreCase("CLEARCACHE_ADD_PACKAGENAME_WL")){
Log.e(TAG, "received CLEARCACHE_ADD_PACKAGENAME_WL");
String pushGuid = (String)remoteMessageMap.get("pushguid");
Log.e(TAG, "pushGuid = " + pushGuid);
String packageName = (String)remoteMessageMap.get("package_name");
Intent intentExecutePushCommand = new Intent( getApplicationContext(), ExecutePushCommandIntentService.class);
intentExecutePushCommand.putExtra("compID", MenuActivity.companyID);
intentExecutePushCommand.putExtra("command", message);
intentExecutePushCommand.putExtra("pushguid", pushGuid);
intentExecutePushCommand.putExtra("package_name", packageName);
startService(intentExecutePushCommand);
}
There is no need to pass the remoteMessageMap to another class. The source of the problem is the limitation in the java method size. Here is a piece of the official documentation of oracle which is related to this problem:
code_length
The value of the code_length item gives the number of bytes in the code array for this method.
The value of code_length must be greater than zero (as the code array must not be empty) and less than 65536.
The point is that your onMessageReceived method is too long, which is bigger than 64KB of compiled code. It is weird why it was compiled fine in previous versions of Android Studio :)
Anyway, the solution is to break the method into smaller fragments. My suggestion is fragmentation by some message types. For example:
private static final String COMMAND_1 = "COMMAND_1";
private static final String COMMAND_2 = "COMMAND_2";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.e(TAG, "remoteMessage.getData() = " + remoteMessage.getData());
Map remoteMessageMap = remoteMessage.getData();
String message = (String) remoteMessageMap.get("message");
String type = extrated_from_received_message;
switch (type) {
case COMMAND_1:
handleCommand1(remoteMessageMap);
break;
case COMMAND_2:
handleCommand2(remoteMessageMap);
break;
// more commands ...
default:
// ...
}
}
private void handleCommand1(Map remoteMessageMap){
// do whatever related to command 1
}
private void handleCommand2(Map remoteMessageMap){
// do whatever related to command 2
}
In this way, the method size would be optimized and the performance of calling it will be far improved.
It seems that you are repeating the same lines of code a lot of times, just put these lines of code and maybe a few more in a separate method that is called on each else if and this will reduce the size of onMessageReceived()
Intent intentExecutePushCommand = new Intent( getApplicationContext(), ExecutePushCommandIntentService.class);
intentExecutePushCommand.putExtra("compID", MenuActivity.companyID);
intentExecutePushCommand.putExtra("command", message);
intentExecutePushCommand.putExtra("pushguid", pushGuid);
Hi fellow Garmin developers,
I have been trying to develop a direct messaging communication setup over BLE between my Android App and my connectIQ app (on Garmin Forerunner 230, SDK version 1.3.x). The goal here is that the Android app is collecting some data, and then pushing it to the watch app.
Following the details on the developer site, I have managed to get this to work, but there are a lot of dropped messages that don't get sent, and the watch receives fewer values than what is being sent.
On Android, I get this status (ConnectIQ.IQMessageStatus) = FAILURE_DURING_TRANSFER in my debug statements. '240' is the data being sent.
D/GarminMessenger: onMessageStatus: Message: 240, device: Forerunner 230, FAILURE_DURING_TRANSFER
This is my app code on the garmin:
SampleApp.mc
using Toybox.Application as App;
using Toybox.Communications as Comm;
using Toybox.WatchUi as Ui;
using Toybox.System as Sys;
var mailMethod;
var crashOnMessage = false;
var msg;
class SampleApp extends App.AppBase {
function initialize() {
AppBase.initialize();
Sys.println("app-initialize()");
msg = "0";
mailMethod = method(:onMail);
Comm.setMailboxListener(mailMethod);
Sys.println("app-initialize(): mail box listener has been set");
}
// onStart() is called on application start up
function onStart(state) {
System.println("app-onStart()");
}
// Return the initial view of your application here
function getInitialView() {
Sys.println("app-getInitialView()");
return [ new SampleAppView() ];
}
function onMail(mailIter) {
var mail = mailIter.next();
while(mail!=null) {
Sys.println("app-onMail: received - "+mail);
message = mail.toString();
Ui.requestUpdate();
mail = mailIter.next();
}
Comm.emptyMailbox();
}
// onStop() is called when your application is exiting
function onStop(state) {
System.println("app-onStop()");
}
}
class CommListener extends Comm.ConnectionListener {
function initialize() {
Comm.ConnectionListener.initialize();
sys.println("commlistener-initialize");
}
function onComplete() {
Sys.println("commlistener-onComplete: Transmit Complete");
}
function onError() {
Sys.println("commlistener-onError: Transmit Failed");
}
}
Any ideas on what could be causing this issue? I am performing all the necessary checks on the Android side to verify if the Garmin watch is paired and connected (&the app is open).
One reason this could be happening is that I am trying to send 1-2 data values (each with a ConnectIQ.sendMessage()) every second, so perhaps the Garmin device/BLE module does not support communication at that rate?
Thanks in advance for solutions and suggestions.
I think that the Connect messaging system just gets into some broken state and then no messages will go through.
What you could try is to set up the Mailbox listener in onStart method instead of initialize.
Also there is a new method to make the message reading a lot easier. It is still largely undocumented, but I got a word it will be documented with the next SDK release. However, it is already working on every ConnectIQ watch.
The method is:
Comm.registerForPhoneAppMessages(method(:onMsg));
where in your callback method you do:
function onMsg(msg) {
handleIncomingMessage(msg.data.toString());
}
or something similar. The input object msg is of class
Toybox::Communications::Message
probably (this is not documented yet).
So I posted a similar question on the Garmin developer forum here, and got a partial answer to my problem. Posting a summary from there.
What I was hoping to implement was something life the following:
Assuming the messages from Android are 1, 2, 3, 4, 5: I would like the
app to do update the UI as the messages are received, in real-time like this:
app-onMail: received - 1
//update the UI
app-onMail: received - 2
//update the UI
app-onMail: received - 3
//update the UI
app-onMail: received - 4
//update the UI
app-onMail: received - 5
//update the UI
Instead, this happens
app-onMail: received - 1
app-onMail: received - 2
app-onMail: received - 3
app-onMail: received - 4
app-onMail: received - 5
//update the UI
//update the UI
//update the UI
//update the UI
//update the UI
THE ANSWER
The framework polls to see if there are new, unread mail messages. If there are any, it invokes the application onMail() callback which consumes each message from the queue, and repeatedly sets a flag that indicates the UI needs to update. After the call returns, the framework checks the flag to see if the UI needs to be updated, and if so it calls onUpdate() for the active view.
As such, I could only display every message if I send messages from Android at 5sec intervals. I could not find a way to receive and display data at higher rates due to its message polling frequency.
My responder suggested maintaining a queue of mail items (or just a counter) and then handling the mail items between draws, like this:
class MyApp extends App.AppBase
{
hidden var _M_messages;
hidden var _M_count;
function initialize() {
AppBase.initialize();
_M_messages = new [10];
_M_count = 0;
}
function getInitialView() {
return [ new MyView() ];
}
function onStart(params) {
Comm.setMailboxListener(self.method(:onMail));
}
function onStop(params) {
Comm.setMailboxListener(null);
}
function onMail(mailIter) {
var mail = mailIter.next();
while (mail != null) {
// only track up to 10 messages
if (_M_count < 10) {
_M_messages[_M_count] = mail;
++_M_count;
}
else {
break;
}
mail = mailIter.next();
}
Comm.emptyMailbox();
startProcessingMessages();
}
hidden function startProcessingMessages() {
if (_M_timer == null) {
_M_timer = new Timer.Timer();
_M_timer.start(self.method(:processOneMessage), 250, true);
}
}
hidden function stopProcessingMessages() {
if (_M_timer != null) {
_M_timer.stop();
_M_timer = null;
}
}
function getMessageCount() {
return _M_messages;
}
function processOneMessage() {
if (_M_count != 0) {
--_M_count;
var mail = _M_messages[_M_count];
_M_messages[_M_count] = null;
// process the message here
Ui.requestUpdate();
if (_M_count == 0) {
stopProcessingMessages();
}
}
}
}
class MyView extends Ui.View
{
hidden var _M_app;
function initialize(app) {
View.initialize();
_M_app = app;
}
function onUpdate(dc) {
var mailMessages = _M_app.getMessageCount();
// draw the number of mail messages
}
}
I work with camera2API on Samsung S5 and if i try get state of focus i get value 0 which is equals to CaptureResult.CONTROL_AF_STATE_INACTIVE...
There is snip of code :
private void process(CaptureResult result) {
switch (mState) {
case CameraHelper.STATE_PREVIEW: {
// We have nothing to do when the camera preview is working normally.
here i get ---> Integer afState = result.get(CaptureResult.CONTROL_AF_STATE);
if (CaptureResult.CONTROL_AF_TRIGGER_START == afState) {
if (areWeFocused) {
Log.e("---!!! HERE !!!--- :", String.valueOf(areWeFocused));
}else {
}
}
if (CaptureResult.CONTROL_AF_STATE_PASSIVE_FOCUSED == afState) {
areWeFocused = true;
} else {
areWeFocused = false;
}
break;
}
But i also tried to test it on my Meizu MX5 and i get 1 - CaptureResult.CONTROL_AF_TRIGGER_START or 2 - CaptureResult.CONTROL_AF_STATE_PASSIVE_FOCUSED
Question is : what is the difference in my code? Why do i get 0 in one case and 1 or 2 in another?
I know this is an old question, but i just ran into the same issue. Read through the Android docs about ControlAfState (AF = Auto Focus for those who are unaware, like I was). If AutoFocus Mode (afMode) is set to AF_MODE_OFF you will get the ControlAfState of Inactive.
Android CaptureResult.CONTROL_AF_STATE
This is related with handling the scenario when some crazy user is holding down the F5 key to send unlimited requests to our server.
Our application is very much database and cache intensive and when such consecutive requests come in; our web application is crashing after some time. I know we need to fix the application cache handling and need to add some check at the web server but I am asked to take care of this issue in our code.
I am handling this on both Javascript and server side, but looks like still it is failing, so would like to know if you have any better solution.
My code is as follows:
Javascript Code:
function checkPageRefresh(e) {
e = e || window.event;
ar isPageRefreshed = false;
// detect if user tries to refresh
if ((e.keyCode == 116) /* F5 */ ||
(e.ctrlKey && (e.keyCode == 116)) /* Ctrl-F5 */ ||
(e.ctrlKey && (e.keyCode == 82)) /* Ctrl-R */) {
isPageRefreshed = true;
}
// only trigger special handling for page refresh
if (isPageRefreshed){
var lastRefreshTimeMillis= readCookie("last_refresh");
var currentTimeMillis = new Date().getTime();
// set cookie with now as last refresh time
createCookie(lastRefreshCookieName, currentTimeMillis);
var lastRefreshParsed = parseFloat(lastRefreshTimeMillis, 10);
var timeDiff = currentTimeMillis - lastRefreshParsed;
var F5RefreshTimeLimitMillis = <%=request.getAttribute("F5RefreshTimeLimitMillis")%>;
// if detected last refresh was within 1 second, abort refresh
if (timeDiff < F5RefreshTimeLimitMillis) {
if (e.preventDefault) {
e.preventDefault();
return;
}
}
} // end if (isPageRefreshed)
}
Java Code:
Queue<VisitsInfoHolder> recentlyVisitedUrls = (LinkedList<VisitsInfoHolder>)session.getAttribute(SupportWebKeys.RECENTLY_VISITED_URLS);
String urlBeingCalled = PageUrlUtils.getFullURL(request);
int maxCountOfRecentURLs = 3;
if(null != recentlyVisitedUrls){
//verify if last visit count is matching with the count provided
if(recentlyVisitedUrls.size() >= maxCountOfRecentURLs ) {
int noOfMatchingVisits = 0;
Long firstAccessedTime = 0l;
int count = 0;
for(VisitsInfoHolder urlIno : recentlyVisitedUrls) {
//Store the time stamp of the first record
if(count == 0 && null != urlIno) {
firstAccessedTime = urlIno.getTimeOfTheVisit();
}
count++;
//count how many visits to the current page
if(null != urlIno && null != urlIno.getUrl() && urlIno.getUrl().equalsIgnoreCase(urlBeingCalled)) {
noOfMatchingVisits++;
}
}
if (noOfMatchingVisits >= maxCountOfRecentURLs && (new Date().getTime() - firstAccessedTime) <= 1000){
LOGGER.error(">>>>> Redirecting the client to the warning page.");
VisitsInfoHolder currentVisitInfo = new VisitsInfoHolder(urlBeingCalled,new Date().getTime());
recentlyVisitedUrls.remove();
recentlyVisitedUrls.add(currentVisitInfo);
response.sendRedirect((String)request.getAttribute("F5IssueRedirectPage"));
LOGGER.error(">>>>> Redirected successfully.");
return;
}
else{
VisitsInfoHolder currentVisitInfo = new VisitsInfoHolder(urlBeingCalled,new Date().getTime());
recentlyVisitedUrls.remove();
recentlyVisitedUrls.add(currentVisitInfo);
session.setAttribute(SupportWebKeys.RECENTLY_VISITED_URLS, recentlyVisitedUrls);
}
}
else if (recentlyVisitedUrls.size() < maxCountOfRecentURLs) {
VisitsInfoHolder currentVisitInfo = new VisitsInfoHolder(urlBeingCalled,new Date().getTime());
recentlyVisitedUrls.add(currentVisitInfo);
session.setAttribute(SupportWebKeys.RECENTLY_VISITED_URLS, recentlyVisitedUrls);
}
}
else{
recentlyVisitedUrls = new LinkedList<VisitsInfoHolder>();
VisitsInfoHolder currentVisitInfo = new VisitsInfoHolder(urlBeingCalled,new Date().getTime());
recentlyVisitedUrls.add(currentVisitInfo);
session.setAttribute(SupportWebKeys.RECENTLY_VISITED_URLS, recentlyVisitedUrls);
}
Now I keep holding the F5 button then my Javascript is not understanding that the same key is held for longer time and server side code prints the following 2 loggers
Redirecting the client to the warning page.
Redirected successfully.
But in reality it is not redirecting any single time. I tried adding Thread.sleep(1000) before and after redirect, but still no luck.
Please let me know if you see any issue with my code or let me know if there is any better solution.
When you reproduce this problem are you the only person on your server? Can you reproduce this problem on your local dev instance? If so you really need to fix your server code such that it doesn't crash. You are doing something on your server that is too intensive and needs to be optimized.
Simply intercepting the F5 key on someone's browser is treating the symptoms not the disease. If you are having problems handling a single user hitting F5 really quickly it simply means you'll never be able to scale up to many simultaneous users because that's the exact same request/response pattern as a single user round tripping you with F5.
It's time to break out the profiler and check the timings on how long it takes to process a single request through the system. Then look for hotspots and optimize it. Also watch your memory usage see if you are cleaning things up or if they are growing off into infinity.