I made an app whos purpose is to download and set wallpaper in set intervals.
User can choose to do that only when connected to wifi or not.
Relevant code:
mWallpaperButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mSwitchWifi.isChecked()) {
mConnectivity = mConnectionDetector.isConnectedToWifi();
} else {
mConnectivity = mConnectionDetector.isConnectedToInternet();
}
if (mConnectivity) {
my code here
}
The code above works fine for setting the wallpaper the first time.
My problem is, I need the Service to check if the user wants to update wallpaper only over WIFI before doing so. At the moment, wallpaper is updated regardless of mSwitchWifi state. (which is bad, because it can use mobile data and user sometimes doesn't want that.)
I tried running similar Switch code in Service but I can't because it must be called in a UI Thread.
I also tried couple of workarounds and Intent.putExtra but I get exception:
NullPointerException: Attempt to invoke virtual method on a null object reference
Any idea how to check network state in service?
My service code atm:
public static class Service extends IntentService {
public Service() {
super("wallpaperchanger-download");
}
#Override
protected void onHandleIntent(Intent intent) {
if (url == null) {
SharedPreferences sharedPreferences = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
String getUrl = sharedPreferences.getString(pref_urlKey, null);
if (getUrl != null) {
url = getUrl;
}
}
wm = WallpaperManager.getInstance(this);
try {
InputStream input = new URL(url).openStream();
Log.v(TAG, url);
wm.setStream(input);
input.close();
} catch (Exception e) {
e.printStackTrace();
}
loading = false;
Log.v(TAG, "Service Running Url " + url);
}
}
If you question is how to access the user selection inside a service/runnable/thread then you can use shared preferences to achieve this. So in your case when the user selects the choice for the first time you want to do something like this:
if(mSwitchWifi.isChecked()) { // i guess this is no wifi
SharedPreferences sharedPreferences = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
Editor editor = sharedPeredences.edit()
editor.putBoolean("isWifi", false)
} else { // guessing this is wifi
SharedPreferences sharedPreferences = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
Editor editor = sharedPeredences.edit()
editor.putBoolean("isWifi", true)
}
This is this code to check if it is true or false:
mWallpaperButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Boolean isWifi = isWifi()
if (!isWifi) { // i guess this is if not wifi
mConnectivity = mConnectionDetector.isConnectedToWifi();
} else if (isWifi) { // guessing this is wifi
mConnectivity = mConnectionDetector.isConnectedToInternet();
}
}
}
public Boolean isWifi() { // you can call this inside your service
SharedPreferences sharedPreferences = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
Boolean wifiState = sharedPreferences.getBoolean("isWifi", true)
return wifiState;
}
This is just a very rough implementation to give an idea of how you can do it, you can improve this many ways. For example you could put the if statement thats inside the onClickListener in the isWifi() function and just call isWifi() inside your runnable/thread...
you can set list preferences to auto update functions based on the network ....
You can create separate class to check the connectivity and from that class you can select the preferences like auto update only on wifi or when connected to network or do not auto update ....
Related
I'm developing a mobile app using ApacheCordova/Phonegap.
I need a function that sends a SMS to me once per install. If I put my function on "DeviceReady" it will be run each time the app opens.
Is there any solution for a function to be run when app is installed OR when it runs for first time?
Any suggestion would be appreciated.
Check if it is the first time with a method and then perform the action if that method determines that it is the first time.
Ex:
isFirstTime() Method
private boolean isFirstTime()
{
SharedPreferences preferences = getPreferences(MODE_PRIVATE);
boolean ranBefore = preferences.getBoolean("RanBefore", false);
if (!ranBefore) {
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("RanBefore", true);
editor.commit();
// Send the SMS
}
return ranBefore;
}
You may want to add it to your onCreate()
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
topLevelLayout = findViewById(R.id.top_layout);
if (isFirstTime()) {
topLevelLayout.setVisibility(View.INVISIBLE);
}
I added a field to the localstorage and on startup just check if that field exists. So something like this:
if (window.localStorage.getItem("installed") == undefined) {
/* run function */
window.localStorage.setItem("installed", true);
}
Edit: The reason I prefer this over the other methods is that this works on iOS, WP, etc as well, and not only on android
This should be what u are searching for:
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
if(!prefs.getBoolean("firstTime", false))
{
// run your one time code
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean("firstTime", true);
editor.commit();
}
Use some boolean value if its true don't call that function other wise call that function example is here
if(smssent!=true)
{
//call sms sending method
}
else
{
//just leave blank or else notify user using some toast message
}
Note:-the boolean value store in some database like sharedprefernce or sqllite, files....
I've added the SharedPreferences functionality to my App to launch a specific activity once the App starts after it has been quited.
I use the following code to save the string:
final SharedPreferences pref1 = getSharedPreferences("myapp", MODE_PRIVATE);
SharedPreferences.Editor editor = pref1.edit();
editor.putString("Stringval", "view1");
editor.commit();
Then the following to load the last used activity, this code is below OnCreate
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final SharedPreferences pref1 = getSharedPreferences("myapp", MODE_PRIVATE);
String str1= pref1.getString("Stringval", null);
if(str1 == "view0")
{
setContentView(R.layout.activity_view0);
}
else if(str1 == "view1")
{
setContentView(R.layout.activity_view1);
}
else
{
setContentView(R.layout.activity_no_setup);
}
}
The code works if the user just quits the App, then relaunches it (Only tested it in the Simulator so far) but whenever I use the task manager to force quit the app like this:
The App just relaunches without using the SharedPreferences.
What's the reason for the App to not load the SharedPreferences or is this just a simulator bug?
You can write
if(str1 != null && str1.equals("view0"))
{
setContentView(R.layout.activity_view0);
}
else if(str1 != null && str1.equals("view1"))
{
setContentView(R.layout.activity_view1);
}
else
{
setContentView(R.layout.activity_no_setup);
}
try this, May be helpful for you......
In one of my app i wanted to check the service state of the android phone
before sending sms. I have used the following code to do that
//check service
ServiceState pstate = new ServiceState();
if(pstate.getState() != ServiceState.STATE_IN_SERVICE)
{
Log.v(TAG,"service state" +pstate.getState());
Toast.makeText(Myactivity.this, "error string", 2000).show();
return;
}
But the code always returns with OUT_OF_SERVICE ( value of 1 in +pstate.getState)
Please let me know what is the reliable way to check whether the phone is in STATE_IN_SERVICE or not?
This code was checked in FROYO version.
Not a satisfactory answer really, but I've had he same problem and kept wasting time, but it would just not work on my FROYO version aswell.
But using the TelephonyManager and PhoneStateListener this worked perfectly fine. For your case I'd suggest using a wrapper instead of instantiating the ServiceState directly, ie
//declare current state
ServiceState myServiceState = new ServiceState();
PhoneStateListener listener = null; // not sure if this is needed really..
// nifty getter
public ServiceState getServiceState(){ return myServiceState; }
//setup listener (eg. in onCreate)
TelephonyManager tm = (TelephonyManager) context.getSystemService(context.TELEPHONY_SERVICE);
listener = new PhoneStateListener() {
#Override
public void onServiceStateChanged(ServiceState serviceState){
myServiceState = serviceState;
}
};
tm.listen(listener,PhoneStateListener.LISTEN_SERVICE_STATE);
// to be called when destroying your context
public void unregisterListener(){
// something like..
tm.listen(listener,PhoneStateListener.LISTEN_NONE);
}
//check service
ServiceState pstate = getServiceState();
if(pstate.getState() != ServiceState.STATE_IN_SERVICE)
{
Log.v(TAG,"service state" +pstate.getState());
Toast.makeText(Myactivity.this, "error string", 2000).show();
return;
}
A lazier solution would be moving the listener-setup into the getter and registering it only when actually called, if ever, and only saving if the service is available. ie
//declaration
boolean isAvailable = false;
PhoneStateListener listener = null;
// more nifty getter
public boolean isServiceAvailable(){
if (listener == null){
//setup listener if not yet done
TelephonyManager tm = (TelephonyManager) context.getSystemService(context.TELEPHONY_SERVICE);
listener = new PhoneStateListener() {
#Override
public void onServiceStateChanged(ServiceState serviceState){
isAvailable = serviceState.getState() == ServiceState.STATE_IN_SERVICE;
}
};
tm.listen(listener,PhoneStateListener.LISTEN_SERVICE_STATE);
}
return isAvailable;
}
// to be called when destroying your context
public void unregisterListener(){
// something like..
if (lister != null){
tm.listen(listener,PhoneStateListener.LISTEN_NONE);
}
}
//check service
if(! isServiceAvailable())
{
Log.v(TAG,"service state" +pstate.getState());
Toast.makeText(Myactivity.this, "error string", 2000).show();
return;
}
But be aware, that would require the listener to get called immediately upon registration, otherwise you'll end up with arbitrary results - so make sure to check that.
I'm trying to read data to my widget after device boot.
My boot receiver is this:
public class onBootReceiver extends BroadcastReceiver{
public static final String TAG = "BootReceiver";
private Context c;
#Override
public void onReceive(Context c, Intent i) {
// TODO Auto-generated method stub
boolean dontStop = true;
while(dontStop)
{
try
{
this.c=c;
if(isExternalStorageMounted())
{
dontStop = false;
}
else
for(int j=0;j<10000;j++)
Log.d(TAG, "###################### EXTERNAL STORAGE NOT MOUNTED ##########################");
}
catch (Exception e)
{
for(int j=0;j<10000;j++)
Log.d(TAG, "###################### EXTERNAL STORAGE NOT MOUNTED ##########################");
}
}
Intent externalStorageReady = new Intent(c, TheWidget.class);
externalStorageReady.setAction(GlobalVars.WIDGET_INTENT_ACTION_READ_PREFS_AFTER_BOOT);
c.sendBroadcast(externalStorageReady);
}
private boolean isExternalStorageMounted()
{
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_REMOVED.equals(state))
{
return false;
}
else if (Environment.MEDIA_SHARED.equals(state))
{
return false;
}
else if (Environment.MEDIA_UNMOUNTABLE.equals(state))
{
return false;
}
else if (Environment.MEDIA_UNMOUNTED.equals(state))
{
return false;
}
return true;
}
}
I know I get the BOOT_COMPLETED intent (after using it in the widget itself), but I just can't read my saved data.
I read that using SharedPreferences is the solution, but what I know is when you boot your device, the SharedPreferences is no longer there.
I save the data internally using built-in SQL in the Android SDK.
Please help... :(
External storage may not be ready by the time of a BOOT_COMPLETED broadcast. And your loops are pointless.
but what i know is when you boot your device, the SharedPreferences is no longer there.
Yes, SharedPreferences are there at boot time.
i save the data internally using built-in SQL in the android sdk.
Then it is unclear why you are waiting on external storage, since your data is not on external storage.
Any form of I/O may take too long, though, right at boot time. Have your BroadcastReceiver call startService() on an IntentService that can read your database or SharedPreferences in onHandleIntent() and update your app widget.
My app copies files over from res/raw to the sdcard on first run. I want it to update those files on every subsequent app update. How can i have it reset the firstrun preference to true on every app update?
Here is the relevant code:
/**
* get if this is the first run
*
* #return returns true, if this is the first run
*/
public boolean getFirstRun() {
return mPrefs.getBoolean("firstRun", true);
}
/**
* store the first run
*/
public void setRunned() {
SharedPreferences.Editor edit = mPrefs.edit();
edit.putBoolean("firstRun", false);
edit.commit();
}
SharedPreferences mPrefs;
/**
* setting up preferences storage
*/
public void firstRunPreferences() {
Context mContext = this.getApplicationContext();
mPrefs = mContext.getSharedPreferences("myAppPrefs", 0); //0 = mode private. only this app can read these preferences
}
public void setStatus(String statustext) {
SharedPreferences.Editor edit = mPrefs.edit();
edit.putString("status", statustext);
edit.commit();
}
}
In my app, I save in my shared preferences the version code of the app. At every startup, I check to see if the saved version code is lower than my current version code. If it is, I show a "what's new" dialog.
Give this code a whirl - I use it in my main activity's onCreate:
PackageInfo pInfo;
try {
pInfo = getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_META_DATA);
if ( prefs.getLong( "lastRunVersionCode", 0) < pInfo.versionCode ) {
// TODO: Handle your first-run situation here
Editor editor = prefs.edit();
editor.putLong("lastRunVersionCode", pInfo.versionCode);
editor.commit();
}
} catch (NameNotFoundException e) {
// TODO Something pretty serious went wrong if you got here...
e.printStackTrace();
}
prefs is a private SharedPreferences object. This works if it's truly the first run, and for upgrades. At the end of the first-run code, the editor.putLong updates your shared preferences with the current version code of your app so the next run doesn't trigger your first-run code.
This also benefits from the fact that your version code must increase for the app to be seen as an upgrade by the market, so you don't need to remember to change a separate value to detect the first-run.
You could mimic what's done on the database side, with version numbers. Instead of having just a firstRun variable, have a couple with firstRun and versionNumber, and put a static version number field in your app, that you increment at each release. This way, you'll be able to check if the app has been updated, and do your operation on each update.
I'm create class for this; download in https://gist.github.com/2509913
Example Use:
long versionInstalled = App.getVersionInstalled(this);
long current_v = App.getVersion(this);
if( versionInstalled != current_v ){
Log.w("TAG", "Veresion not valid");
}
Run this in the MainActivity's OnCreate
public void onUpdateFirstRun () {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
PackageInfo pInfo;
try {
pInfo = getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_META_DATA);
Log.d("VersionCode", pInfo.versionCode + " ");
if (prefs.getLong(LAST_RUN_VERSION_CODE_KEY, 0) < pInfo.versionCode) {
if (!isInitializedInSP(KEY)) {
editor.putString(KEY, "");
}
//Finalize and Save
editor.putLong(LAST_RUN_VERSION_CODE_KEY, pInfo.versionCode);
editor.apply();
}
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
}
Use method to check if you had already initialized it in previous version
public static boolean isInitializedInSP (String key) {
SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContex());
Object o = mPrefs.getAll().get(key);
if (o != null) {
return true;
}
else {
return false;
}
}