Prevent RecyclerView recycling items
recyclerView.getRecycledViewPool().setMaxRecycledViews(VIEW_TYPE,0);
References
https://stackoverflow.com/questions/20721752/prevent-the-adapter-from-recycling-views-on-scroll
recyclerView.getRecycledViewPool().setMaxRecycledViews(VIEW_TYPE,0);
References
https://stackoverflow.com/questions/20721752/prevent-the-adapter-from-recycling-views-on-scroll
FileAlterationObserver observer = new FileAlterationObserver("pathToDir"); FileAlterationMonitor monitor = new FileAlterationMonitor(POLL_INTERVAL); FileAlterationListener listener = new FileAlterationListenerAdaptor() { @Override public void onFileCreate(File file) { // code for processing creation event } @Override public void onFileDelete(File file) { // code for processing deletion event } @Override public void onFileChange(File file) { // code for processing change event } }; observer.addListener(listener); monitor.addObserver(observer); monitor.start();
References
http://www.baeldung.com/java-watchservice-vs-apache-commons-io-monitor-library
BroadcastReceiverOnBootComplete.java
public class BroadcastReceiverOnBootComplete extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equalsIgnoreCase(Intent.ACTION_BOOT_COMPLETED)) { Intent serviceIntent = new Intent(context, AndroidServiceStartOnBoot.class); context.startService(serviceIntent); } } }
AndroidServiceStartOnBoot.java
public class AndroidServiceStartOnBoot extends Service { @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); // here you can add whatever you want this service to do } }
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.javacodegeeks.androidserviceonbootexample"> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"></uses-permission> <receiver android:name="com.javacodegeeks.androidserviceonbootexample.BroadcastReceiverOnBootComplete" android:enabled="true" android:exported="false"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.PACKAGE_REPLACED" /> <data android:scheme="package" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.PACKAGE_ADDED" /> <data android:scheme="package" /> </intent-filter> </receiver> <service android:name="com.javacodegeeks.androidserviceonbootexample.AndroidServiceStartOnBoot"></service> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme"> <activity android:name="com.javacodegeeks.androidserviceonbootexample.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> </application> </manifest >
if we want to be sure our service is sticky
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { if (workerThread == null) { workerThread = Thread(run) workerThread!!.start() Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show(); } return Service.START_STICKY }
and
override fun onTaskRemoved(rootIntent: Intent?) { val restartService = Intent(applicationContext, this.javaClass) restartService.`package` = packageName val restartServicePI = PendingIntent.getService( applicationContext, 1, restartService, PendingIntent.FLAG_ONE_SHOT) val alarmService = applicationContext.getSystemService(Context.ALARM_SERVICE) as AlarmManager alarmService.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + 5000, restartServicePI) }
References
http://blog.vogella.com/2011/12/11/automatically-starting-services-in-android-after-booting/
https://examples.javacodegeeks.com/android/core/activity/android-start-service-boot-example/
http://www.framentos.com/en/android-tutorial/2012/08/01/how-to-start-a-service-at-boot-in-android/
private class PathFileObserver extends FileObserver{ static final String TAG="FILEOBSERVER"; /** * should be end with File.separator */ String rootPath; static final int mask = (FileObserver.CREATE | FileObserver.DELETE | FileObserver.DELETE_SELF | FileObserver.MODIFY | FileObserver.MOVED_FROM | FileObserver.MOVED_TO | FileObserver.MOVE_SELF); public PathFileObserver(String root){ super(root, mask); if (! root.endsWith(File.separator)){ root += File.separator; } rootPath = root; } public void onEvent(int event, String path) { switch(event){ case FileObserver.CREATE: Log.d(TAG, "CREATE:" + rootPath + path); break; case FileObserver.DELETE: Log.d(TAG, "DELETE:" + rootPath + path); break; case FileObserver.DELETE_SELF: Log.d(TAG, "DELETE_SELF:" + rootPath + path); break; case FileObserver.MODIFY: Log.d(TAG, "MODIFY:" + rootPath + path); break; case FileObserver.MOVED_FROM: Log.d(TAG, "MOVED_FROM:" + rootPath + path); break; case FileObserver.MOVED_TO: Log.d(TAG, "MOVED_TO:" + path); break; case FileObserver.MOVE_SELF: Log.d(TAG, "MOVE_SELF:" + path); break; default: // just ignore break; } } public void close(){ super.finalize(); } }
References
https://gist.github.com/shirou/659180
AndroidManifest.xml
<service android:name=".MyService"/>
MyService.java
public class MyService extends Service { Binder mBinder = new LocalService(); @Nullable @Override public IBinder onBind(Intent intent) { return mBinder; } public class LocalService extends Binder { MyService getService() { return MyService.this; } } public String getFirstMessage() { return "Message 1"; } public String getSecondMessage() { return "Message 2"; } }
MainActivity.java
public class MainActivity extends AppCompatActivity { MyService myService = null; Button buttonMessage1; Button buttonMessage2; TextView textViewOutput; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Intent intent = new Intent(MainActivity.this, MyService.class); bindService(intent, serviceConnection, BIND_AUTO_CREATE); buttonMessage1 = (Button) findViewById(R.id.buttonMessage1); buttonMessage2 = (Button) findViewById(R.id.buttonMessage2); textViewOutput = (TextView) findViewById(R.id.textViewOutput); buttonMessage1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (myService != null) { textViewOutput.setText(myService.getFirstMessage()); } } }); buttonMessage2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (myService != null) { textViewOutput.setText(myService.getSecondMessage()); } } }); } ServiceConnection serviceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { MyService.LocalService localService = (MyService.LocalService) iBinder; myService = localService.getService(); } @Override public void onServiceDisconnected(ComponentName componentName) { myService = null; } }; @Override protected void onStop() { super.onStop(); unbindService(serviceConnection); myService = null; } }
References
https://www.youtube.com/watch?v=PUxC6vzEEgg
https://github.com/mhdr/AndroidSamples/tree/master/101
public class MyService extends IntentService { int counter = 0; public MyService() { super("MyServiceThread"); } @Override protected void onHandleIntent(@Nullable Intent intent) { counter++; Handler handler = new Handler(getMainLooper()); handler.post(new Runnable() { @Override public void run() { Toast.makeText(MyService.this, "Service Stared: " + counter, Toast.LENGTH_SHORT).show(); } }); for (int i = 0; i < 10; i++) { try { wait(1500); } catch (Exception e) { e.printStackTrace(); } } } @Override public void onDestroy() { Toast.makeText(MyService.this, "Service Stopped", Toast.LENGTH_SHORT).show(); } }
References
https://www.youtube.com/watch?v=cpq163QF2nM
https://github.com/mhdr/AndroidSamples/tree/master/100
MyService.java
public class MyService extends Service { Thread workerThread = null; int counter=0; @Override public int onStartCommand(Intent intent, int flags, int startId) { final Handler handler = new Handler(getMainLooper()); synchronized (this) { Runnable runnable = new Runnable() { @Override public void run() { handler.post(new Runnable() { @Override public void run() { counter++; Toast.makeText(MyService.this, "Service Started: " + counter, Toast.LENGTH_SHORT).show(); } }); for (int i = 0; i < 10; i++) { try { wait(1500); } catch (Exception e) { e.printStackTrace(); } } } }; if (workerThread == null) { workerThread = new Thread(runnable); workerThread.start(); } } return Service.START_STICKY; } @Override public void onDestroy() { super.onDestroy(); if (workerThread != null) { workerThread.interrupt(); workerThread = null; Toast.makeText(MyService.this, "Service Stopped", Toast.LENGTH_SHORT).show(); } } @Nullable @Override public IBinder onBind(Intent intent) { return null; } }
AndroidManifest.xml
<service android:name=".MyService" />
MainActivity.java
public class MainActivity extends AppCompatActivity { Button buttonStartService; Button buttonStopService; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); buttonStartService = (Button) findViewById(R.id.buttonStartService); buttonStopService = (Button) findViewById(R.id.buttonStopService); buttonStartService.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(MainActivity.this, MyService.class); startService(intent); } }); buttonStopService.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(MainActivity.this, MyService.class); stopService(intent); } }); } }
References
https://www.youtube.com/watch?v=foGmyYe2bV8
https://github.com/mhdr/AndroidSamples/tree/master/099
runOnUiThread() will execute the Runnable immediately. but post() always puts the Runnable at the end of the event queue, even if you are already on the main application thread
// Get a handler that can be used to post to the main thread Handler mainHandler = new Handler(context.getMainLooper()); Runnable myRunnable = new Runnable() { @Override public void run() {....} // This is your code }; mainHandler.post(myRunnable);
MainActivity.this.runOnUiThread(new Runnable() { public void run() { Log.d("UI thread", "I am the UI thread"); } });
References
https://stackoverflow.com/questions/11123621/running-code-in-main-thread-from-another-thread
https://stackoverflow.com/questions/12850143/android-basics-running-code-in-the-ui-thread
MyService.java
public class MyService extends Service { private int counter=0; @Override public void onCreate() { super.onCreate(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { counter++; Toast.makeText(this, "Service Started : " + counter, Toast.LENGTH_SHORT).show(); return Service.START_STICKY; } @Override public void onDestroy() { Toast.makeText(this, "Service Stopped", Toast.LENGTH_SHORT).show(); } @Nullable @Override public IBinder onBind(Intent intent) { return null; } }
MainActivity.java
public class MainActivity extends AppCompatActivity { Button buttonStartService; Button buttonStopService; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); buttonStartService = (Button) findViewById(R.id.buttonStartService); buttonStopService = (Button) findViewById(R.id.buttonStopService); buttonStartService.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(MainActivity.this, MyService.class); startService(intent); } }); buttonStopService.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(MainActivity.this, MyService.class); stopService(intent); } }); } }
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="pupli.net.a098"> <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"> <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=".MyService" /> </application> </manifest>
References
https://www.youtube.com/watch?v=HYctmRwYHOg
https://github.com/mhdr/AndroidSamples/tree/master/098
Method
public int getScreenOrientation() { Display getOrient = getWindowManager().getDefaultDisplay(); int orientation = Configuration.ORIENTATION_UNDEFINED; if(getOrient.getWidth()==getOrient.getHeight()){ orientation = Configuration.ORIENTATION_SQUARE; } else{ if(getOrient.getWidth() < getOrient.getHeight()){ orientation = Configuration.ORIENTATION_PORTRAIT; }else { orientation = Configuration.ORIENTATION_LANDSCAPE; } } return orientation; }
Event
@Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); // Checks the orientation of the screen if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show(); } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){ Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show(); } }
AndroidManifest.xml
<activity android:name=".MyActivity" android:configChanges="orientation|keyboardHidden" android:label="@string/app_name">
References
https://stackoverflow.com/questions/2795833/check-orientation-on-android-phone
https://stackoverflow.com/questions/5726657/how-to-detect-orientation-change-in-layout-in-android