我試圖製作一個應用程序,打開一項服務,每5小時更換手機上的壁紙。爲什麼我的服務進入timertask循環?
出於測試目的,我只是改變了定時器1分鐘只是爲了看看它是否工作(因爲當它有5小時不工作),
確實也改變了牆紙的每一分鐘。即使當我關閉我的應用程序,並關閉服務 我有一個聲明重新啓動它,以便工作。
不幸的是,當手機變黑(屏幕超時)。我把它重新打開就像它一直在卡住。它需要在電話被暫停時進入聽者的內部,因此它會立即進入timerTask內部,例如,立即連續10次(或者它離線的時間,並且應該已經進入內部)。換句話說,如果我把手機靜止10分鐘,然後再打開它,它會連續10次更換我的壁紙。
所以這是一個問題。另一個是如果我改變計時器5個小時,它根本不會改變壁紙。
有人可以幫助我或知道爲什麼發生在我身上?
這是我的代碼>
我的服務>
package com.greenroad.candidate.mywallpaperchanger;
import android.app.Service;
import android.app.WallpaperManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.WindowManager;
import android.widget.Toast;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
/**
* Created by pitsponet on 31/08/2015.
*/
public class myService extends Service {
int oneSecond = 1000;
int oneMinute = oneSecond*60;
int oneHour = oneMinute*60;
int timerDeley = oneMinute;
private Timer timer;
//this is the tast or the reciver the timer will go into every time it has being called
private TimerTask timerTask = new TimerTask() {
@Override
public void run() {
//shows a toast saying timer listener has entered
Handler mainHandler = new Handler(getApplicationContext().getMainLooper());
mainHandler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), "timer listener Entered", Toast.LENGTH_LONG).show();
}
});
//gets the picture modifire to know what picture to choose to change the wallpaper to
// Access the default SharedPreferences
SharedPreferences pref = getApplicationContext().getSharedPreferences("myGlobalPrefTable", MODE_PRIVATE);
SharedPreferences.Editor editor = pref.edit();
Integer pictureModifireInt = pref.getInt("pictureModifire", 0);
//updates teh picture modifire by one
pictureModifireInt++;
/////holds a list with all the images that are avilable to change
int displayPicture = R.drawable.captain;
ArrayList<Integer> pictureNames = new ArrayList<>();
pictureNames.add(R.drawable.captain);
pictureNames.add(R.drawable.flash);
pictureNames.add(R.drawable.superman);
pictureNames.add(R.drawable.thor);
pictureNames.add(R.drawable.wonder);
pictureNames.add(R.drawable.a);
pictureNames.add(R.drawable.b);
pictureNames.add(R.drawable.c);
pictureNames.add(R.drawable.d);
pictureNames.add(R.drawable.e);
pictureNames.add(R.drawable.f);
pictureNames.add(R.drawable.g);
pictureNames.add(R.drawable.h);
pictureNames.add(R.drawable.i);
pictureNames.add(R.drawable.j);
pictureNames.add(R.drawable.k);
pictureNames.add(R.drawable.l);
pictureNames.add(R.drawable.m);
pictureNames.add(R.drawable.n);
pictureNames.add(R.drawable.o);
//logs the stored prefrence and select the correct image at place > picture modifire
Log.d("myLog", "storedPreference: " + pictureModifireInt);
displayPicture = pictureNames.get(pictureModifireInt-1);
//stores the picture modifire back in the shared prefrences or initlizes it if it reached the last image
if(pictureModifireInt > 19){
// Edit the saved preferences
Log.d("myLog", "putting in pictureModifire : : " + 0);
editor.putInt("pictureModifire", 0);
editor.commit();
} else {
Log.d("myLog", "putting in pictureModifire : : " + pictureModifireInt);
editor.putInt("pictureModifire", pictureModifireInt);
editor.commit();
}
//most important part of the code
//gets the dimentions of the phones screen and changes the wallpaper
//it has to get the dimentions so that the wallpaper will be in full screen
//maybe he can't do this part when he is in suspend mode ?
WindowManager wm= (WindowManager) getSystemService(MainActivity.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
Bitmap bmap2 = BitmapFactory.decodeResource(getResources(), displayPicture);
Bitmap bitmap = Bitmap.createScaledBitmap(bmap2, width, height, true);
WallpaperManager wallpaperManager = WallpaperManager.getInstance(getApplicationContext());
try {
wallpaperManager.setBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
//just shoes a post to let knnow what wallpaper has been changed, and that the walpaper indeed changed
mainHandler = new Handler(getApplicationContext().getMainLooper());
final Integer finalPictureModifireInt = pictureModifireInt-1;
mainHandler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), "wallpaper changed to : "+ finalPictureModifireInt+" and started a new timer", Toast.LENGTH_LONG).show();
}
});
}
};
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
//show a toast to indicae that a new service was created
Toast.makeText(getApplicationContext(), "a new service created",
Toast.LENGTH_LONG).show();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("MyLog", "a new service started");
final Handler mainHandler = new Handler(getApplicationContext().getMainLooper());
mainHandler.post(new Runnable() {
@Override
public void run() {
//show a toast to indicae that a new service was started
Toast.makeText(getApplicationContext(), "serviceStarterd", Toast.LENGTH_LONG).show();
// Access the default SharedPreferences
SharedPreferences pref = getApplicationContext().getSharedPreferences("myGlobalPrefTable", MODE_PRIVATE);
SharedPreferences.Editor editor = pref.edit();
//open a boolean to tell if the service is activated for the first time it will say false
boolean serviceStateOn = pref.getBoolean("isServiceActivated", false);
if(serviceStateOn == false){
//if ther serviceStateOn is false then there is no service running and it's fine to run a timer task
Toast.makeText(getApplicationContext(), "a New Timer Started with Delay: "+timerDeley, Toast.LENGTH_LONG).show();
editor.putBoolean("isServiceActivated", true); // getting String
editor.commit();
timer = new Timer();
timer.scheduleAtFixedRate(timerTask, timerDeley, timerDeley);
} else {
//if ther serviceStateOn is true then there is a service runing so just don't do anything
Log.d ("myLog", "Service is on so do nothing");
}
}
});
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(getApplicationContext(), "service stoped",
Toast.LENGTH_LONG).show();
}
}
我的清單文件>
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.greenroad.candidate.mywallpaperchanger" >
<uses-permission android:name="android.permission.SET_WALLPAPER"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".myService"
android:exported="false"
/>
</application>
</manifest>
我的主要acticity>
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.preference.PreferenceManager;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import java.io.IOException;
public class MainActivity extends ActionBarActivity implements View.OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
//declaring all the buttons
Button comixButtonSuperman, comixButtonFlash, comixButtonCaptainAmerica, comixButtonThor, comixButtonWonderWoman;
Button startServiceButton, stopServiceButton;
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//casting and connecting the buttons to the actual buttons
comixButtonSuperman = (Button) findViewById(R.id.BT_wallpaper1);
comixButtonFlash = (Button) findViewById(R.id.BT_wallpaper2);
comixButtonCaptainAmerica = (Button) findViewById(R.id.BT_wallpaper3);
comixButtonThor = (Button) findViewById(R.id.BT_wallpaper4);
comixButtonWonderWoman = (Button) findViewById(R.id.BT_wallpaper5);
startServiceButton = (Button) findViewById(R.id.BT_startService);
stopServiceButton = (Button) findViewById(R.id.BT_stopService);
//adding listeners for all the buttons
comixButtonSuperman.setOnClickListener(this);
comixButtonFlash.setOnClickListener(this);
comixButtonCaptainAmerica.setOnClickListener(this);
comixButtonThor.setOnClickListener(this);
comixButtonWonderWoman.setOnClickListener(this);
startServiceButton.setOnClickListener(this);
stopServiceButton.setOnClickListener(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d ("myLog", "Application exists here");
// when going to suspend the service is destroyd, so we should change the boolean to indicate this
//also this will make the service statement added in the service possible.
SharedPreferences pref = getApplicationContext().getSharedPreferences("myGlobalPrefTable", MODE_PRIVATE);
SharedPreferences.Editor editor7 = pref.edit();
editor7.putBoolean("isServiceActivated", false); // getting String
editor7.commit();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
//maybe will add options in a later date
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.BT_wallpaper1: // superman button
//was used for testings
break;
case R.id.BT_wallpaper2: // flash button
//was used for testings
break;
case R.id.BT_wallpaper3: // captain america button
//was used for testings
break;
case R.id.BT_wallpaper4: // thor button
//was used for testings
break;
case R.id.BT_wallpaper5: // wonder woman button
//was used for testings
break;
case R.id.BT_startService: // starts the service
//starts the service up
Intent i= new Intent(this, myService.class);
startService(i);
break;
case R.id.BT_stopService: // stops the service
//stop the service
Intent j= new Intent(this, myService.class);
stopService(j);
//updates ths shared prefrence that there is no service suning any moew
SharedPreferences pref = getApplicationContext().getSharedPreferences("myGlobalPrefTable", MODE_PRIVATE);
SharedPreferences.Editor editor7 = pref.edit();
editor7.putBoolean("isServiceActivated", false); // getting String
editor7.commit();
break;
}
}
}