I'm trying to code the game loop for an android game, however, i've come across this error when trying to access the current time (you know, for FPS management etc)
"SystemClock() is not public in 'android.os.SystemClock'. Cannot be accessed from outside package"
My code:
import android.os.SystemClock;
//...
SystemClock clock = new SystemClock();
Can you help me please? ^_^
SystemClock exposes static methods. So you should access them like this:
SystemClock.sleep(1000);
boolean b = SystemClock.setCurrentTimeMillis(1000)
long l = SystemClock.currentThreadTimeMillis();
Related
is there any way to change an android device time from a cordova app?
I need to sync the device time with a server.
The app gets the server time from a webapi and if it's different from the device time i'd like to change the device time.
Thanks
You should not try to bend the whole device just to make your app work. What if the server-time is wrong? What if the user wants a different time?
We have the same needs for our app, and what we are doing is to run the app in server-time.
This is native Android in Java, but I think the idea should be clear and should also be possible in Cordova.
So we have this ServerTime class, and whenever we need the current time in our app, we do not use new Date() or System.currentTimeMillis(), but instead use ServerTime.now().
The class looks something like this (written from memory and simplified, make sure to test, maybe the diff-calculations should be + instead of - ...):
public static class ServerTime {
private static long diffMillis;
public static Date now() {
long millis = System.currentTimeMillis() - diffMillis;
return new Date(millis;
}
public static void update(long serverTimeMillis) {
diffMillis = System.currentTimeMillis() - serverTimeMillis;
}
}
The server provides the server's time with every response and additionally we poll the server-time every 15 minutes or so. Whenever we get the server's time, we call ServerTime.update(server's time in millis).
I am developing an Android App in Air for Android using Flash Pro CC & I am tired of pushing updates all the time to change a spawn location for an image that needs to move every few days to a specific location. I won't know the location until just minutes before the update needs to be pushed & it would be much faster to simply have the app load the spawn coordinates for the image upon launch from my website in a .txt file. I would need something where I just type the X and Y coordinates in a file & then the information is loaded and AS3 spawns the image at those coordinates. If no coordinates are available in the text file (as 5 days of the week there won't be), I need a different image to be displayed wherever I place it. I will probably just have a separate frame for that though.
Any help is greatly appreciated & I'd prefer it if the image can be used in a motion tween but if not then I will work something out.
NOTE: I am new to AS3 coding but I have Flash itself figured out for animating with the timeline.
Have a look at URLRequest and URLLoader for retrieving the data. For spawning the image at a specific location, consider just moving it instead; Any object on stage is a DisplayObject, and DisplayObjects have properties x and y. For swapping out the images, look at DisplayObjectContainer, specifically the functions DisplayObjectContainer.addChild(child:DisplayObject) and DisplayObjectContainer.removeChild(child:DisplayObject). I have provided links to the documentation for each of the relevant functions.
If the update is on a daily basis, have a look at the Date class too - that will allow you to find out what date it is and whether you need to make an url request to load the textfile to display the image.
If you have any specific questions regarding the use of these classes, I think it's best if you make a new question with a link back to this one for context. You're good with English, not so good with AS3 (as you say), so I could explain the relevant bits where needed, but it would be a long and complex story if I were to explain this entire functionality in one go. ... I think you'll find that these class names will make googling easier too.
I expect that you'll have to use an URLLoader with an URLRequest to load the textfile, then depending on the results, display the image by adding it to stage via addChild if it's not there yet, and then setting its x and y values. You'll have to use the Date class to check whether you need to make a new request every time the user starts the application or does some specific action.
I have the finished code here. loadURL is the Document Class loaded by Flash. Everything works great!
package {
// IMPORTS EVENTS USED
import flash.display.MovieClip;
import flash.net.URLRequest;
import flash.net.URLLoader;
import flash.events.UncaughtErrorEvent;
import flash.events.ErrorEvent;
import flash.events.Event;
// DECLARES VARIABLES
public class loadURL extends MovieClip {
public var Xurl:String = "URL GOES HERE";
public var Yurl:String = "URL GOES HERE";
public var URLloaderX:URLLoader = new URLLoader();
public var URLloaderY:URLLoader = new URLLoader();
public var marker:Marker = new Marker();
public var gone:Gone = new Gone();
public var connectionerr:ConnectionErr = new ConnectionErr();
// CODE EXECUTED UPON LAUNCH
public function loadURL() {
// constructor code
trace("Loaded");
URLloaderX.addEventListener(Event.COMPLETE, completeHandlerX);
URLloaderX.load(new URLRequest(Xurl));
URLloaderY.addEventListener(Event.COMPLETE, completeHandlerY);
URLloaderY.load(new URLRequest(Yurl));
loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, onUncaughtError);
}
function completeHandlerX(event:Event):void
{
if(URLloaderX.data == null||URLloaderX.data==(""))
{addChild(gone)}
else{addChild(marker);marker.x = (URLloaderX.data)}
}
function completeHandlerY(event:Event):void
{
if(URLloaderY.data == null||URLloaderY.data==("")){}
marker.y = (URLloaderY.data)
}
private function onUncaughtError(e:UncaughtErrorEvent):void //Checks for no internet connection
{
e.preventDefault(); //leave this
// RESULT OF NO INTERNET HERE
addChild(connectionerr);
}
}
}
I have two issues with this, my very first android app. The first is that I noticed after I installed the app the battery started draining about twice as fast as before. I read an article on this that stated sometimes programmers make an error which causes this. This being my first app, the probability is pretty high that this is the case.
The second issue is that I can save my variables when the app is turned off, but when the phone is turned off the data is lost.
As for the code, it's mostly bits and pieces from stuff I've found online and tried to incorporate. It's a simple calculator with three variables. Ideally, I'd like to store b and c, but allow the user to overwrite them. Variable a will change with each use, so no need to store that.
Here's my Main:
package com.kwagz.calc;
import android.app.Activity;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends Activity {
String g, e;
String b; //changed(sorry)
String c; //changed
SharedPreferences sh_Pref;
Editor toEdit;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
loadSavedPreferences();
}
public void calculateClickHandler(View view) {
if (view.getId() == R.id.button1) {
EditText a = (EditText)findViewById(R.id.a);
EditText b = (EditText)findViewById(R.id.b);
EditText c = (EditText)findViewById(R.id.c);
TextView output = (TextView)findViewById(R.id.textView9);
double gp = Double.parseDouble(a.getText().toString());
int ab = Integer.parseInt(b.getText().toString());
int ac = Integer.parseInt(c.getText().toString());
double t = ((gp / ab) * ac);
output.setText(String.format("%.2f", t));
}
}
public void sharedPreferences() {
SharedPreferences saved_values =//there's no linebreak here in my code
PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
SharedPreferences.Editor editor=saved_values.edit();
editor.putString("b", b);
editor.putString("c", c);
editor.commit();
}
private void loadSavedPreferences() {
SharedPreferences saved_values =//there's no linebreak here in my code
PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
b = saved_values.getString("b", g);
}
}
From reading what you said, the only logical explanation forming in my head is: You are starting background service from your App, while background service is running it makes app run all the time which explains why variables are stored until phone is turned off (when background service gets killed).
Okay, let's take your questions one at a time. The battery problem could be a number of things, without knowing more details about your program I couldn't possibly diagnose it completely. Android does have some good power saving tips. The key item is to minimize the use of connectivity devices to no more than is required. The two biggest culprits are GPS and Internet connections. If your app isn't running, then the only way it could be running the batteries is if there's threads in the background, or maybe something like an AlarmService.
You are using SharedPreferences correctly, the value should be saved, but I think you should but the saving code in onSaveInstanceState(). If you do that, it should work fine.
EDIT
Upon closer inspection, you're fundementally saving the wrong thing. You should save the value of the EditText, not the EditText itself. In fact, I'd simply remove all references to String a,b,c, move the EditText definitions to the top to replace them, and do something like this:
editor.putString("b", b.getText().toString());
b.setText(saved_values.getString("b", g));
I've conducted several tests in an effort to recreate the issue, with no success. I'm still working on the sharedPreferences thing, but the battery drain (I suspect) was caused by another app which just happened to coincide with the installation of mine.
As I mentioned in my note to arleitiss, my Y!Mail was showing the highest amount of battery drain. A day or two after posting the note my account started acting up and then became "inactive". Once I reset it, the app no longer appears on the Battery list.
Thanks for all the input!
I am trying to get a list of running applications and the amount of battery used by each of them. I have google for a long time but didnt come up with a solution. However there have been a few references on the PowerProfile, PowerUsageSummary internal classes.
I used them through Reflection technique but didnt get what i was looking for. PowerUsageSummary shows the same details as you can see by going to Device Settings->Applications->Battery Use(This is how it can be seen in a Samsund device).
Then i used PowerProfile class but i got only the mA of current utilized by WIFI, AUDIO, VIDEO,GPS, BLUETOOTH etc(The mA values dont change so often. I am not sure if the values are correct). Another reference was the BatteryStatsImpl class. I tested this class but the values are 0 always. Still i am looking for the list of running applications and the amount of battery used by each of them. Any help is appreciated.
Thanks,
Here is the sample code that i tried for BatteryStatsImpl class.
String BATTERY_PROFILE_CLASS = "com.android.internal.os.BatteryStatsImpl";
Object mBatteryProfile = Class.forName(BATTERY_PROFILE_CLASS).getConstructor().newInstance();
Method batteryMeth = Class.forName(BATTERY_PROFILE_CLASS).getMethod("getBatteryUptime", long.class);
Object arglist1[] = new Object[1];
arglist1[0] = System.currentTimeMillis();
// This is to calculate the batteryUpTime since the current time.
Long batteryUptime = (Long) batteryMeth.invoke(mBatteryProfile, arglist1);
Method dischargeMeth = Class.forName(BATTERY_PROFILE_CLASS).getMethod("getDischargeStartLevel");
// This is to calculate the dischargeTime of the device battery
Integer dischargeTime = (Integer) dischargeMeth.invoke(mBatteryProfile);
First please note that you can't make use of this API unless you are installed on the system image and so can hold the BATTERY_STATS permission. This is not available to third part apps installed separately from the system.
To use this, you don't directly instantiate BatteryStatsImpl. You request an instance of it from the current stats being collected by BatteryStatsService. You can look for the source code of the settings app for how to do this: https://code.google.com/p/android-source-browsing/source/browse/src/com/android/settings/fuelgauge/PowerUsageSummary.java?repo=platform--packages--apps--settings
In particular:
import android.os.BatteryStats;
import com.android.internal.app.IBatteryStats;
import com.android.internal.os.BatteryStatsImpl;
IBatteryStats mBatteryInfo;
UserManager mUm;
BatteryStatsImpl mStats;
mBatteryInfo = IBatteryStats.Stub.asInterface(
ServiceManager.getService("batteryinfo"));
private void load() {
try {
byte[] data = mBatteryInfo.getStatistics();
Parcel parcel = Parcel.obtain();
parcel.unmarshall(data, 0, data.length);
parcel.setDataPosition(0);
mStats = com.android.internal.os.BatteryStatsImpl.CREATOR
.createFromParcel(parcel);
mStats.distributeWorkLocked(BatteryStats.STATS_SINCE_CHARGED);
} catch (RemoteException e) {
Log.e(TAG, "RemoteException:", e);
}
}
the BatteryStatsService maintains the stats. Have a look in there how BatteryStatsImpl is used to do that (those note*() methods are called by the system when e.g. screen turns on)
Maybe you can get the current stats from there
Is it possible to capture MMI result in Android?
I need to do things like put on hold, merge calls, etc. and as the only telephony events in android are NEW_OUTGOING_CALL, RINGING, OFFHOOK and IDLE, I need to get the result when i dial any MMI code like Held Code.
Is it possible?
The best solution for me would be to find some way to discover when an outgoing call gets actually connected. Maybe has somebody find any workaround for that?
I made some progress in that question reading system logs (LogCat) and searching for determinate strings, but it seems that logs differs between models and SO versions so this is not a consistent aproach.
Thanks for your help!
Maybe you can get it using RIL(Radio Interface Layer)
try something like:
1) adb device shell
2) logcat -b radio
// Navigate to the page that you have dial *#06# in dialpad then execute jar below to get the IMEI result
import com.android.uiautomator.core.UiObject;
import com.android.uiautomator.testrunner.UiAutomatorTestCase;
import com.android.uiautomator.core.UiSelector;
import com.android.uiautomator.core.UiObjectNotFoundException;
import com.android.uiautomator.core.UiScrollable;
import android.util.Log;
public class SIM_Info_Reader_png extends UiAutomatorTestCase{
public void getPromptedIMEI() throws UiObjectNotFoundException {
UiObject list = new UiObject(new UiSelector().resourceId("android:id/text1"));
int i = 0;
System.out.println("IMEI=" + list.getText());
}
}