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;
}
}
Related
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.
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 am working on an application for collecting crash reports in application, so that I have created class which extends Application for handling uncaught exception and created service class for communicate with server.
I made a simple divide by zero exception in a button click and it produce exception but my service class does not called. I am sure have registered the service class in manifest file.
my question is Will Service concept work even if application is crashed (force close) in Android?
code:
public class MyApp extends Application {
public void onCreate() {
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread thread, Throwable e) {
handleUncaughtException(thread, e);
}
});
}
public void handleUncaughtException(Thread thread, Throwable e) {
e.printStackTrace();
Intent i = new Intent(MyApp.this, ServiceClass.class);
startService(i);
}
}
Service class:
public class ServiceClass extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public void onLowMemory() {
super.onLowMemory();
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e("onStartCommand", "onStartCommand called");
// server communication code.
return Service.START_STICKY;
}
}
Manifest xml file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ex.errorhandle"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="21" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:name="com.ex.errorhandle.MyApp"
android:allowBackup="true"
android:icon="#drawable/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="com.ex.errorhandle.ServiceClass" />
</application>
</manifest>
When clicked on the button on activity_main (button1) I would like to test the ChatClientService.
In the method onStartCommand i want to run a thread which uses the innerclass as runnable. This is were it goes wrong: the intent works (log shows aaaaa) and it goes into the run method (log shows aaaaa) but I do not manage to go into the innerclass. Any ideas? (sorry for the logs)
ChatClientService.java
public class ChatClientService extends Service {
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//TODO do something useful
new Thread( new Runnable() {
#Override
public void run() {
Log.i("aaaaaaaaaaaaaaaaaaaa","aaaaaaaaaaaaaaaaaaaa");
}
}).start();
return Service.START_NOT_STICKY;
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
public class ChatClient implements Runnable {
private BufferedWriter bw;
private BufferedReader br;
private boolean running;
public void halt() {
Log.i("DDDDDDDDDDDDDDDDDD","DDDDDDDDDDDDDDDDDD");
running = true;
try {
bw.close();
bw = null;
br.close();
br = null;
} catch (IOException e) {
Log.i("EEEEEEEEEEEEEEEEE","EEEEEEEEEEEEEEEEEEE");
}
}
#Override
public void run() {
Log.i("HHHHHHHHHHHHHHH", "HHHHHHHHHHHHHHH");
try {
running = true;
Socket s = new Socket("<your pc ip>", 9999);
this.br = new BufferedReader(new InputStreamReader(s.getInputStream()));
this.bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
String in = null;
while(running && (in = br.readLine()) != null) {
Log.i("CHATCLIENT RECV ", in);
}
} catch (UnknownHostException e) {
e.printStackTrace();
Log.i("FFFFFFFFFFFFFFFF","FFFFFFFFFFFFFFF");
} catch (IOException e) {
e.printStackTrace();
Log.i("GGGGGGGGGGGGG","GGGGGGGGGGG");
}
}
}
}
MainActivity.java
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void TestChat(View v){
Log.i("cccccccccccccccccccccccccc","cccccccccccccccccccccc");
startService(new Intent(getApplication(), ChatClientService.class));
}
}
Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="be.howest.mad.lab24.oef1"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="18"
android:targetSdkVersion="18" />
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="be.howest.mad.lab24.oef1.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="be.howest.mad.lab24.oef1.ChatClientService"
android:enabled="true"
android:exported="false" >
</service>
</application>
</manifest>
Thanks in advance!
try this...
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
new Thread(new ChatClient()).start();
return START_NOT_STICKY;
}
I'm trying to use this very simple Service and BroadcastReceiver but I'm getting a
ClassNotFound exception. If I don't use startService things are fine so the problem it's with the receiver. I have registered it in the android manifest file so why do I get the ClassNotFound exception?
I will be using this method of communication for polling a php file and updating a ListView. Is this the appropriate way of communicating (broadcast intent)?
public class MessengerServiceActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
startService(new Intent(this,MessengerService.class));
}
class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Bundle b=intent.getExtras();
if(b==null)
return;
String msg=b.getString("message");
TextView tv=(TextView) findViewById(R.id.textView1);
tv.setText(msg);
}
}
}
public class MessengerService extends Service {
HttpClient hc;
HttpPost hp;
String s[]={"pratik","harsha","dayal","hritika"};
public MessengerService() {
// TODO Auto-generated constructor stub
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
hc=new DefaultHttpClient();
}
#Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Thread t=new Thread(new Runnable(){
public void run()
{
int k=0;
while(true)
{
Intent i=new Intent("com.pdd.messenger.MyAction");
i.putExtra("message",s[k]);
sendBroadcast(i);
try
{
Thread.sleep(3000);
}
catch (InterruptedException e)
{
Toast.makeText(getApplicationContext(), e.getLocalizedMessage(), Toast.LENGTH_LONG)
.show();
}
k=(k+1)%4;
}
}
});
t.start();
return super.onStartCommand(intent, flags, startId);
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.pdd.messenger"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name=".MessengerServiceActivity"
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=".MyReceiver" android:enabled="true">
<intent-filter>
<action android:name="com.pdd.messenger.MyAction"/>
</intent-filter>
</receiver>
<service android:name=".MessengerService"></service>
</application>
</manifest>