I'm trying to make an auto click app with AccessibilityService. I use method dispatchGesture with a AccessibilityService.GestureResultCallback to perform click on the screen and repeat it in onCompleted(). The problem is if I touch the screen before gesture completed, the gesture cancelled (onCancelled fired). How could I prevent screen touch stop my gesture?
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.falcon.autoclick">
<application
android:name=".base.App"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.AutoClick">
<activity android:name=".ManageConfigActivity" />
<activity android:name=".TestActivity" />
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".FloatingMenu"
android:enabled="true"
android:exported="false" />
<service
android:name=".AutoService"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="#xml/global_action_bar_service" />
</service>
</application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
#xml/global_action_bar_service
<?xml version="1.0" encoding="utf-8"?>
<accessibility-service
xmlns:android="http://schemas.android.com/apk/res/android"
android:accessibilityFeedbackType="feedbackGeneric"
android:accessibilityFlags="flagDefault"
android:canPerformGestures="true"
android:description="#string/app_name"
android:notificationTimeout="100"
android:settingsActivity=".MainActivity" />
AutoService.java
public static final String EXTRA_ACTION = "auto_service_action";
public static final String ACTION_START_AUTO = "start_auto_click";
public static final String ACTION_STOP_AUTO = "stop_auto_click";
public static final String EXTRA_TARGET = "extra_target";
private Handler handler;
private IntervalRunnable runnable;
private CountDownTimer startTimer;
private CountDownTimer endTimer;
#Override
public void onCreate() {
super.onCreate();
HandlerThread handlerThread = new HandlerThread("auto-handler");
handlerThread.start();
handler = new Handler(handlerThread.getLooper());
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
String action = intent.getAction();
if (action != null) {
if (action.equals(ACTION_START_AUTO)) {
Target target = (Target) intent.getSerializableExtra(EXTRA_TARGET);
runnable = new IntervalRunnable(target);
handler.postDelayed(runnable, 100);
} else if (action.equals(ACTION_STOP_AUTO)) {
stopAuto();
}
}
return super.onStartCommand(intent, flags, startId);
}
private void stopAuto() {
if (startTimer != null) {
startTimer.cancel();
}
if (endTimer != null) {
endTimer.cancel();
}
handler.removeCallbacks(runnable);
runnable = null;
}
private void startSingleTarget(Target target) {
dispatchGesture(getGestureDescription(target), new AccessibilityService.GestureResultCallback() {
#Override
public void onCompleted(GestureDescription gestureDescription) {
super.onCompleted(gestureDescription);
LogUtil.d("stopwatch", "gesture completed");
startTimer = new CountDownTimer(target.getDelayTime(), 1000) {
#Override
public void onTick(long l) {
}
#Override
public void onFinish() {
handler.post(runnable);
}
}.start();
}
#Override
public void onCancelled(GestureDescription gestureDescription) {
super.onCancelled(gestureDescription);
LogUtil.d("testttttt", "gesture cancelled");
}
}, null);
}
private GestureDescription getGestureDescription(Target target) {
long duration = 0;
GestureDescription.Builder gestureBuilder = new GestureDescription.Builder();
Path path = new Path();
path.moveTo(target.getCenterStartX(), target.getCenterStartY());
if (target.isSwipe()) {
path.lineTo(target.getCenterEndX(), target.getCenterEndY());
duration = target.getSwipeDuration();
} else {
duration = target.getClickDuration();
}
gestureBuilder.addStroke(new GestureDescription.StrokeDescription(path,
0,
duration));
return gestureBuilder.build();
}
private class IntervalRunnable implements Runnable {
private Target target;
public IntervalRunnable(Target target) {
this.target = target;
}
#Override
public void run() {
startSingleTarget(target);
}
}
How could I prevent screen touch stop my gesture?
You can't do that by dispatchGesture. From the official documentation about dispatchGesture: Dispatch a gesture to the touch screen. Any gestures currently in progress, whether from the user, this service, or another service, will be cancelled. Thus, gestures dispatched by your service can be canceled by user.
Related
I am developing an application that sends location data to a database. As I need this task to be executed in the background, I used the Service type to send the data, but when the application goes to the background, the service stops executing after a few seconds. I researched the subject and found the JobScheduler class, but this class performs services in the background with a very long time interval (15min) and I needed the service to be performed at least every 2 min and to be canceled only by the user. Is there a way to do this? I thank anyone who can help.
https://developer.android.com/reference/android/app/job/JobScheduler
My service:
public class GPSservice extends Service {
private String TAG = "INICIAR SERVIÇO GPS";
private Context context;
private HandlerThread handlerThread;
private Handler handler;
private final int TEMPO_ENTRE_NOTIFICAÇOES_SEGUNDOS = 60; //tempo de sessenta segundos
#Override
public void onCreate() {
handlerThread = new HandlerThread("HandlerThread");
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(TAG, "onStartCommand");
//Previne que seja executado em subsequentes chamadas a onStartCommand
if(!handlerThread.isAlive()) {
Log.d("NotifyService","Notificações iniciadas");
handlerThread.start();
handler = new Handler(handlerThread.getLooper());
Runnable runnable = new Runnable() {
#Override
public void run() {
AtualizarLocalizacaoBanco();
handler.postDelayed(this, 1000 * TEMPO_ENTRE_NOTIFICAÇOES_SEGUNDOS);
}
};
handler.post(runnable);
}
return Service.START_NOT_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d("NotifyService","Notificações Finalizadas");
Intent broadcastIntent = new Intent(this, BroadCastReceiver.class);
sendBroadcast(broadcastIntent);
//handlerThread.quit();
}
#Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
}
public void AtualizarLocalizacaoBanco(){
context = this;
ModeloAtualizacao model = new ModeloAtualizacao();
SharedPreferences preferences = this.context.getSharedPreferences("user_preferences", MODE_PRIVATE);
model.setId(preferences.getString("usuario_id", ""));
model.setLati(preferences.getString("user_latitude", ""));
model.setLongi(preferences.getString("user_longitude", ""));
model.setEmpresa(preferences.getString("usuario_empresa", ""));
model.setEscola(preferences.getString("usuario_escola", ""));
Call<String> call = new RetrofitConfig().postAtualizacao().atualizarLocalizacao(model);
call.enqueue(new Callback<String>() {
#Override
public void onResponse(Call<String> call, Response<String> response) {
Log.d("Sucesso: ", "ok");
}
#Override
public void onFailure(Call<String> call, Throwable t) {
Log.d("Erro atualizar", t.getMessage());
}
});
}
Manifest:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme"
android:usesCleartextTraffic="true">
<activity android:name=".ActivityGPS"></activity>
<activity android:name=".Activity_Lista_Aluno" />
<activity
android:name=".ProfessorActivity"
android:label="#string/title_activity_professor" />
<service
android:name=".GPSservice"
android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="false"/>
<activity
android:name=".MainActivity"
android:theme="#style/AppTheme.NoActionBar" />
<activity android:name=".Activity_Login">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
I have this application i want to install it (it is service) but i don't have an activity so i can't install it on my device to try it can someone help me please i guess this is livewallpaper for photo sequence like slideshow so can anyone tell me what should i do?
public class MainActivity extends WallpaperService{
Handler handler;
private boolean visible;
public void onCreate()
{
super.onCreate();
}
public void onDestroy()
{
super.onDestroy();
}
public Engine onCreateEngine()
{
return new CercleEngine();
}
class CercleEngine extends Engine
{
public Bitmap image1, image2, image3;
CercleEngine()
{
image1 = BitmapFactory.decodeResource(getResources(), R.drawable.greenww);
image2 = BitmapFactory.decodeResource(getResources(), R.drawable.redww);
image3 = BitmapFactory.decodeResource(getResources(), R.drawable.screen3);
}
public void onCreate(SurfaceHolder surfaceHolder)
{
super.onCreate(surfaceHolder);
}
public void onOffsetsChanged(float xOffset, float yOffset, float xStep, float yStep, int xPixels, int yPixels)
{
drawFrame();
}
void drawFrame()
{
final SurfaceHolder holder = getSurfaceHolder();
Canvas c = null;
try
{
c = holder.lockCanvas();
if (c != null)
{
c.drawBitmap(image1, 0, 0, null);
c.drawBitmap(image2, 0, 0, null);
c.drawBitmap(image3, 0, 0, null);
}
} finally
{
if (c != null) holder.unlockCanvasAndPost(c);
}
handler.removeCallbacks(drawRunner);
if (visible)
{
handler.postDelayed(drawRunner, 1000); // delay 1 sec
}
}
private final Runnable drawRunner = new Runnable()
{
#Override
public void run() {
drawFrame();
}
};
}
manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.mike.wallpaper2">
<uses-permission android:name="android.permission.SET_WALLPAPER" />
<uses-permission android:name="android.permission.SET_WALLPAPER" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<service
android:enabled="true"
android:name=".MainActivity">
<intent-filter>
<action
android:name = "me.myapp.MyAppService">
</action>
</intent-filter>
</service>
<receiver android:enabled="true"
android:name=".BootUpReceiver">
<intent-filter> <action
android:name = "android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
</application>
BootUpReceiver
public class BootUpReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
/***** For start Service ****/
Intent myIntent = new Intent(context, MainActivity.class);
context.startService(myIntent);
}
add/update this code in manifest
<service
android:enabled="true"
android:name=".MainActivity">
<intent-filter>
<action
android:name = "com.example.mike.wallpaper2.MainActivity">
</action>
</intent-filter>
</service>
<receiver
android:enabled="true"
android:name=".BootReceiver">
<intent-filter>
<action android:name = "android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
also add one new class
public class BootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent service = new Intent(context, MainActivity.class);
context.startService(service);
}
}
then follow steps mentioned in following example Start android application without activity
or restart your device this service start running
From EditConfiguration LUNCH OPTION (NOTHING)
I can listen volume level in my VolumeService. This service listen to volume level in background.
My problem is: I can't control volume in lock screen.
I tried two different ways for volume control
First Way with CCL
Application Class:
public class CastApplication extends Application {
private static String APPLICATION_ID;
public static final double VOLUME_INCREMENT = 0.03;
#Override
public void onCreate() {
super.onCreate();
APPLICATION_ID = getString(R.string.app_id);
// initialize VideoCastManager
VideoCastManager.initialize(this, APPLICATION_ID, VideoCastControllerActivity.class, null).
setVolumeStep(VOLUME_INCREMENT).enableFeatures(VideoCastManager.FEATURE_NOTIFICATION |VideoCastManager.FEATURE_LOCKSCREEN |
VideoCastManager.FEATURE_WIFI_RECONNECT | VideoCastManager.FEATURE_CAPTIONS_PREFERENCE |VideoCastManager.FEATURE_DEBUGGING);
}
}
MainActivity:
public class MainActivity extends FragmentActivity {
private VideoCastManager mCastManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
VideoCastManager.checkGooglePlayServices(this);
mCastManager = VideoCastManager.getInstance();
Intent i1 = new Intent(this,VolumeService.class);
startService(i1);
}
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (mCastManager.onDispatchVolumeKeyEvent(event, CastApplication.VOLUME_INCREMENT)) {
return true;
}
return super.dispatchKeyEvent(event);
}
}
Second way without CCL (with RRC)
MainActivity:
public class MainActivity extends FragmentActivity {
ContentObserver mSettingsContentObserver;
RemoteControlClient remoteControlClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON);
AudioManager mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
mAudioManager.requestAudioFocus(null, AudioManager.STREAM_RING,AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
RemoteControlClientCompat mRemoteControlClientCompat = new RemoteControlClientCompat(PendingIntent.getBroadcast(this.getApplicationContext(), 0,intent, 0));
RemoteControlHelper.registerRemoteControlClient(mAudioManager,mRemoteControlClientCompat);
remoteControlClient = new RemoteControlClient((PendingIntent.getBroadcast(this.getApplicationContext(), 0,intent, 0)));
MediaRouter.getInstance(this.getApplicationContext()).addRemoteControlClient(remoteControlClient);
Intent i1 = new Intent(this,VolumeService.class);
startService(i1);
}
}
Service and ContentObserver are same for both way
VolumeService:
public class VolumeService extends Service {
ContentObserver mSettingsContentObserver;
#Override
public void onCreate() {
super.onCreate();
mSettingsContentObserver = new SettingsContentObserver(this, new Handler());
getApplicationContext().getContentResolver().registerContentObserver(
android.provider.Settings.System.CONTENT_URI, true,mSettingsContentObserver);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
super.onDestroy();
getApplicationContext().getContentResolver().unregisterContentObserver(mSettingsContentObserver);
}
}
ContentObserver:
public class SettingsContentObserver extends ContentObserver {
int previousVolume;
Context context;
public SettingsContentObserver(Context c, Handler handler) {
super(handler);
context = c;
AudioManager mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
previousVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_RING);
}
#Override
public boolean deliverSelfNotifications() {
return super.deliverSelfNotifications();
}
#Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
AudioManager audio = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
int currentVolume = audio.getStreamVolume(AudioManager.STREAM_RING);
int delta = previousVolume - currentVolume;
if (delta > 0) {
Log.i("MyService", "Volume is down");
previousVolume = currentVolume;
} else if (delta < 0) {
Log.i("MyService", "Volume is up");
previousVolume = currentVolume;
}
}
}
Manifest:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="18" />
<application
android:name="com.yns.volumelock.CastApplication"
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<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>
<receiver android:name="com.google.android.libraries.cast.companionlibrary.remotecontrol.VideoIntentReceiver" >
<intent-filter>
<action android:name="android.media.AUDIO_BECOMING_NOISY" />
<action android:name="android.intent.action.MEDIA_BUTTON" />
<action android:name="com.google.android.libraries.cast.companionlibrary.action.toggleplayback" />
<action android:name="com.google.android.libraries.cast.companionlibrary.action.stop" />
</intent-filter>
</receiver>
<service
android:name="com.google.android.libraries.cast.companionlibrary.notification.VideoCastNotificationService"
android:exported="false" >
<intent-filter>
<action android:name="com.google.android.libraries.cast.companionlibrary.action.toggleplayback" />
<action android:name="com.google.android.libraries.cast.companionlibrary.action.stop" />
<action android:name="com.google.android.libraries.cast.companionlibrary.action.notificationvisibility" />
</intent-filter>
</service>
<service android:name="com.google.android.libraries.cast.companionlibrary.cast.reconnection.ReconnectionService" />
<activity
android:name="com.google.android.libraries.cast.companionlibrary.cast.tracks.CaptionsPreferenceActivity"
android:label="#string/action_settings" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
<service
android:name="com.yns.volumelock.VolumeService"
android:enabled="true" >
</service>
</application>
I use AIDL interface IExtendedNetworkService to get USSD code. But application only work after reboot device. I tried bindservice after install app but it didn't work. So my problem is how way to bind service without reboot device . This is my code:
interface:
package com.android.internal.telephony;
interface IExtendedNetworkService {
void setMmiString(String number);
CharSequence getMmiRunningText();
CharSequence getUserMessage(CharSequence text);
void clearMmiString();
}
Service
public class CDUSSDService extends Service {
private String TAG = "THANG-NGUYEN";
private boolean mActive = false;
BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_INSERT)) {
// activity wishes to listen to USSD returns, so activate this
mActive = true;
Log.d(TAG, "activate ussd listener");
} else if (intent.getAction().equals(Intent.ACTION_DELETE)) {
mActive = false;
Log.d(TAG, "deactivate ussd listener");
}
}
};
private final IExtendedNetworkService.Stub mBinder = new IExtendedNetworkService.Stub() {
public void clearMmiString() throws RemoteException {
Log.d(TAG, "called clear");
}
public void setMmiString(String number) throws RemoteException {
Log.d(TAG, "setMmiString:" + number);
}
public CharSequence getMmiRunningText() throws RemoteException {
if (mActive == true) {
return null;
}
return "USSD Running";
}
public CharSequence getUserMessage(CharSequence text)
throws RemoteException {
Log.d(TAG, "get user message " + text);
if (mActive == false) {
// listener is still inactive, so return whatever we got
Log.d(TAG, "inactive " + text);
return text;
}
// listener is active, so broadcast data and suppress it from
// default behavior
// build data to send with intent for activity, format URI as per
// RFC 2396
Uri ussdDataUri = new Uri.Builder()
.scheme(getBaseContext().getString(R.string.uri_scheme))
.authority(
getBaseContext().getString(R.string.uri_authority))
.path(getBaseContext().getString(R.string.uri_path))
.appendQueryParameter(
getBaseContext().getString(R.string.uri_param_name),
text.toString()).build();
sendBroadcast(new Intent(Intent.ACTION_GET_CONTENT, ussdDataUri));
mActive = false;
return null;
}
};
public void onCreate() {
Log.i(TAG, "called onCreate");
};
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "called onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
#Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "called onbind");
// the insert/delete intents will be fired by activity to
// activate/deactivate listener since service cannot be stopped
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_INSERT);
filter.addAction(Intent.ACTION_DELETE);
filter.addDataScheme(getBaseContext().getString(R.string.uri_scheme));
filter.addDataAuthority(
getBaseContext().getString(R.string.uri_authority), null);
filter.addDataPath(getBaseContext().getString(R.string.uri_path),
PatternMatcher.PATTERN_LITERAL);
registerReceiver(receiver, filter);
return mBinder;
}
}
MainActivity:
public class MainActivity extends Activity {
private Button btnCheckUSSD;
private Context mContext;
private IExtendedNetworkService mService;
private EditText inputUSSD;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = this;
setContentView(R.layout.activity_main);
btnCheckUSSD = (Button) findViewById(R.id.btn_check);
inputUSSD = (EditText) findViewById(R.id.input_ussd);
btnCheckUSSD.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
if (!inputUSSD.getText().toString().isEmpty()) {
Intent service = new Intent(
"com.android.ussd.IExtendedNetworkService");
bindService(service, mConnecton, Context.BIND_AUTO_CREATE);
startActivity(new Intent("android.intent.action.CALL", Uri
.parse("tel:" + inputUSSD.getText().toString()
+ Uri.encode("#"))));
}
}
});
}
ServiceConnection mConnecton = new ServiceConnection() {
#Override
public void onServiceDisconnected(ComponentName name) {
mService = null;
}
#Override
public void onServiceConnected(ComponentName name, IBinder iBinder) {
mService = IExtendedNetworkService.Stub
.asInterface((IBinder) iBinder);
}
};
protected void onDestroy() {
super.onDestroy();
Log.d("THANG-NGUYEN", "onDestroy");
unbindService(mConnecton);
}
}
Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="info.example.checkussdcode"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="7"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.WRITE_SMS" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="info.example.checkussdcode.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="info.example.checkussdcode.service.UssdCodeService"
android:process=":remote" >
<intent-filter>
<action android:name="com.android.ussd.IExtendedNetworkService" >
</action>
</intent-filter>
</service>
<receiver android:name="info.example.checkussdcode.RebootReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
I'm code up a simple wallpaper service, similar to this one(Android app to change wallpaper at regular intervals using Timer).
The wallpaper is stuck forever at "Loading live wallpaper..." although the images I tried to draw are tiny (2kb png).
My manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.TestWallpaper">
<uses-sdk android:minSdkVersion="15"/>
<uses-feature android:name="android.software.live_wallpaper" />
<application android:icon="#drawable/icon"
android:label="#string/app_name"
android:permission="android.permission.BIND_WALLPAPER">
<service android:name=".Wallpaper"
android:label="#string/app_name"
android:icon="#drawable/icon">
<intent-filter>
<action android:name="android.service.wallpaper.WallpaperService" />
</intent-filter>
<meta-data android:name="android.service.wallpaper"
android:resource="#xml/livewallpaper" />
</service>
</application>
</manifest>
And my main class file:
public class Wallpaper extends Service {
Timer mytimer;
int initialStart= 0;
int interval=60000;
Drawable drawable;
WallpaperManager wpm;
int prev=1;
#Override
public void onCreate() {
super.onCreate();
Log.i("TestWallPaper=>", "print");
mytimer=new Timer();
wpm= WallpaperManager.getInstance(Wallpaper.this);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
mytimer.schedule(new TimerTask() {
#Override
public void run() {
Log.i("TestWallPaper=>", "inside onStartCommand");
if(prev==1){
Log.i("TestWallPaper=>", "prev==1");
drawable = getResources().getDrawable(R.drawable.blue_pin);
prev=2;
}
else if(prev==2){
Log.i("TestWallPaper=>", "prev==2");
drawable = getResources().getDrawable(R.drawable.red_pin);
prev=3;
}
else{
Log.i("TestWallPaper=>", "prev==3");
drawable = getResources().getDrawable(R.drawable.green_pin);
prev=1;
}
Bitmap wallpaper=((BitmapDrawable)drawable).getBitmap();
try {
wpm.setBitmap(wallpaper);
} catch (IOException e) {
Log.e("TestWallPaper=>", "inside onStartCommand");
e.printStackTrace();
}
}
}, initialStart,interval);
return super.onStartCommand(intent, flags, startId);
}
#Override
public IBinder onBind(Intent arg0) {
Log.i("TestWallPaper=>", "inside onBind");
return null;
}
}