Sync adapter with every min requesting value from server.

suggest change
<provider
        android:name=".DummyContentProvider"
        android:authorities="sample.map.com.ipsyncadapter"
        android:exported="false" />

    <!-- This service implements our SyncAdapter. It needs to be exported, so that the system
    sync framework can access it. -->
    <service android:name=".SyncService"
        android:exported="true">
        <!-- This intent filter is required. It allows the system to launch our sync service
        as needed. -->
        <intent-filter>
            <action android:name="android.content.SyncAdapter" />
        </intent-filter>
        <!-- This points to a required XML file which describes our SyncAdapter. -->
        <meta-data android:name="android.content.SyncAdapter"
            android:resource="@xml/syncadapter" />
    </service>

    <!-- This implements the account we'll use as an attachment point for our SyncAdapter. Since
    our SyncAdapter doesn't need to authenticate the current user (it just fetches a public RSS
    feed), this account's implementation is largely empty.

    It's also possible to attach a SyncAdapter to an existing account provided by another
    package. In that case, this element could be omitted here. -->
    <service android:name=".AuthenticatorService"
        >
        <!-- Required filter used by the system to launch our account service. -->
        <intent-filter>
            <action android:name="android.accounts.AccountAuthenticator" />
        </intent-filter>
        <!-- This points to an XMLf ile which describes our account service. -->
        <meta-data android:name="android.accounts.AccountAuthenticator"
            android:resource="@xml/authenticator" />
    </service>

This code need to be add in manifest file

In above code we have the syncservice and conteprovider and authenticatorservice.

In app we need to create the xml package to add syncadpter and authenticator xml files. authenticator.xml

<?xml version="1.0" encoding="utf-8"?>

<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
    android:accountType="@string/R.String.accountType"
    android:icon="@mipmap/ic_launcher"
    android:smallIcon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    />

syncadapter

<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android"
    android:contentAuthority="@string/R.String.contentAuthority"
    android:accountType="@string/R.String.accountType"
    android:userVisible="true"
    android:allowParallelSyncs="true"
    android:isAlwaysSyncable="true"
    android:supportsUploading="false"/>

Authenticator

import android.accounts.AbstractAccountAuthenticator;
import android.accounts.Account;
import android.accounts.AccountAuthenticatorResponse;
import android.accounts.NetworkErrorException;
import android.content.Context;
import android.os.Bundle;

public class Authenticator extends AbstractAccountAuthenticator {
    private Context mContext;
    public Authenticator(Context context) {
        super(context);
         this.mContext=context;
    }

    @Override
    public Bundle editProperties(AccountAuthenticatorResponse accountAuthenticatorResponse, String s) {
        return null;
    }

    @Override
    public Bundle addAccount(AccountAuthenticatorResponse accountAuthenticatorResponse, String s, String s1, String[] strings, Bundle bundle) throws NetworkErrorException {
        return null;
    }

    @Override
    public Bundle confirmCredentials(AccountAuthenticatorResponse accountAuthenticatorResponse, Account account, Bundle bundle) throws NetworkErrorException {
        return null;
    }

    @Override
    public Bundle getAuthToken(AccountAuthenticatorResponse accountAuthenticatorResponse, Account account, String s, Bundle bundle) throws NetworkErrorException {
        return null;
    }

    @Override
    public String getAuthTokenLabel(String s) {
        return null;
    }

    @Override
    public Bundle updateCredentials(AccountAuthenticatorResponse accountAuthenticatorResponse, Account account, String s, Bundle bundle) throws NetworkErrorException {
        return null;
    }

    @Override
    public Bundle hasFeatures(AccountAuthenticatorResponse accountAuthenticatorResponse, Account account, String[] strings) throws NetworkErrorException {
        return null;
    }
}

AuthenticatorService

public class AuthenticatorService extends Service {

    private Authenticator authenticator;

    public AuthenticatorService() {
        super();
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        IBinder ret = null;
        if (intent.getAction().equals(AccountManager.ACTION_AUTHENTICATOR_INTENT)) ;
        ret = getAuthenticator().getIBinder();
        return ret;
    }

    public Authenticator getAuthenticator() {
        if (authenticator == null)
            authenticator = new Authenticator(this);
        return authenticator;
    }
}

IpDataDBHelper

public class IpDataDBHelper extends SQLiteOpenHelper {
   private static final int DATABASE_VERSION=1;
   private static final String DATABASE_NAME="ip.db";
   public static final String TABLE_IP_DATA="ip";

   public static final String COLUMN_ID="_id";
   public static final String COLUMN_IP="ip";
   public static final String COLUMN_COUNTRY_CODE="country_code";
   public static final String COLUMN_COUNTRY_NAME="country_name";
   public static final String COLUMN_CITY="city";
   public static final String COLUMN_LATITUDE="latitude";
   public static final String COLUMN_LONGITUDE="longitude";

   public IpDataDBHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
       super(context, DATABASE_NAME, factory, DATABASE_VERSION);
   }

   @Override
   public void onCreate(SQLiteDatabase sqLiteDatabase) {
       String CREATE_TABLE="CREATE TABLE " + TABLE_IP_DATA + "( " + COLUMN_ID + " INTEGER PRIMARY KEY ,"
               + COLUMN_IP + " INTEGER ," + COLUMN_COUNTRY_CODE + " INTEGER ," + COLUMN_COUNTRY_NAME +
               " TEXT ," + COLUMN_CITY + " TEXT ," + COLUMN_LATITUDE + " INTEGER ," + COLUMN_LONGITUDE + " INTEGER)";
       sqLiteDatabase.execSQL(CREATE_TABLE);
       Log.d("SQL",CREATE_TABLE);
   }

   @Override
   public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
       sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + TABLE_IP_DATA);
       onCreate(sqLiteDatabase);
   }

   public long AddIPData(ContentValues values)
   {
       SQLiteDatabase sqLiteDatabase =getWritableDatabase();
       long insertedRow=sqLiteDatabase.insert(TABLE_IP_DATA,null,values);
       return insertedRow;
   }

   public Cursor getAllIpData()
   {
       String[] projection={COLUMN_ID,COLUMN_IP,COLUMN_COUNTRY_CODE,COLUMN_COUNTRY_NAME,COLUMN_CITY,COLUMN_LATITUDE,COLUMN_LONGITUDE};
       SQLiteDatabase sqLiteDatabase =getReadableDatabase();
       Cursor cursor = sqLiteDatabase.query(TABLE_IP_DATA,projection,null,null,null,null,null);
       return cursor;
   }

   public int deleteAllIpData()
   {
       SQLiteDatabase sqLiteDatabase=getWritableDatabase();
       int rowDeleted=sqLiteDatabase.delete(TABLE_IP_DATA,null,null);
       return rowDeleted;
   }
}

MainActivity

public class MainActivity extends AppCompatActivity {

   private static final String ACCOUNT_TYPE="sample.map.com.ipsyncadapter";
   private static final String AUTHORITY="sample.map.com.ipsyncadapter";
   private static final String ACCOUNT_NAME="Sync";

   public TextView mIp,mCountryCod,mCountryName,mCity,mLatitude,mLongitude;
   CursorAdapter cursorAdapter;
   Account mAccount;
   private String TAG=this.getClass().getCanonicalName();
   ListView mListView;
   public SharedPreferences mSharedPreferences;
   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);
       mListView = (ListView) findViewById(R.id.list);
       mIp=(TextView)findViewById(R.id.txt_ip);
       mCountryCod=(TextView)findViewById(R.id.txt_country_code);
       mCountryName=(TextView)findViewById(R.id.txt_country_name);
       mCity=(TextView)findViewById(R.id.txt_city);
       mLatitude=(TextView)findViewById(R.id.txt_latitude);
       mLongitude=(TextView)findViewById(R.id.txt_longitude);
       mSharedPreferences=getSharedPreferences("MyIp",0);
       
//Using shared preference iam displaying values in text view. 
       String txtIp=mSharedPreferences.getString("ipAdr","");
       String txtCC=mSharedPreferences.getString("CCode","");
       String txtCN=mSharedPreferences.getString("CName","");
       String txtC=mSharedPreferences.getString("City","");
       String txtLP=mSharedPreferences.getString("Latitude","");
       String txtLN=mSharedPreferences.getString("Longitude","");

       mIp.setText(txtIp);
       mCountryCod.setText(txtCC);
       mCountryName.setText(txtCN);
       mCity.setText(txtC);
       mLatitude.setText(txtLP);
       mLongitude.setText(txtLN);

       mAccount=createSyncAccount(this);
//In this code i am using content provider to save data.
      /* Cursor cursor=getContentResolver().query(MyIPContentProvider.CONTENT_URI,null,null,null,null);
       cursorAdapter=new SimpleCursorAdapter(this,R.layout.list_item,cursor,new String []{"ip","country_code","country_name","city","latitude","longitude"},
                                                           new int[] {R.id.txt_ip,R.id.txt_country_code,R.id.txt_country_name,R.id.txt_city,R.id.txt_latitude,R.id.txt_longitude},0);

       mListView.setAdapter(cursorAdapter);
       getContentResolver().registerContentObserver(MyIPContentProvider.CONTENT_URI,true,new StockContentObserver(new Handler()));
*/
       Bundle settingBundle=new Bundle();
       settingBundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL,true);
       settingBundle.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED,true);
       ContentResolver.requestSync(mAccount,AUTHORITY,settingBundle);
       ContentResolver.setSyncAutomatically(mAccount,AUTHORITY,true);
       ContentResolver.addPeriodicSync(mAccount,AUTHORITY,Bundle.EMPTY,60);
   }

   private Account createSyncAccount(MainActivity mainActivity) {
       Account account=new Account(ACCOUNT_NAME,ACCOUNT_TYPE);
       AccountManager accountManager=(AccountManager)mainActivity.getSystemService(ACCOUNT_SERVICE);
       if(accountManager.addAccountExplicitly(account,null,null))
       {

       }else
       {

       }
       return account;
   }

   private class StockContentObserver extends ContentObserver {
       @Override
       public void onChange(boolean selfChange, Uri uri) {
           Log.d(TAG, "CHANGE OBSERVED AT URI: " + uri);
           cursorAdapter.swapCursor(getContentResolver().query(MyIPContentProvider.CONTENT_URI, null, null, null, null));
       }

       public StockContentObserver(Handler handler) {
           super(handler);

       }
   }
   @Override
   protected void onResume() {
       super.onResume();
       registerReceiver(syncStaredReceiver, new IntentFilter(SyncAdapter.SYNC_STARTED));
       registerReceiver(syncFinishedReceiver, new IntentFilter(SyncAdapter.SYNC_FINISHED));
   }

   @Override
   protected void onPause() {
       super.onPause();
       unregisterReceiver(syncStaredReceiver);
       unregisterReceiver(syncFinishedReceiver);
   }
   private BroadcastReceiver syncFinishedReceiver = new BroadcastReceiver() {

       @Override
       public void onReceive(Context context, Intent intent) {
           Log.d(TAG, "Sync finished!");
           Toast.makeText(getApplicationContext(), "Sync Finished", Toast.LENGTH_SHORT).show();
       }
   };
   private BroadcastReceiver syncStaredReceiver = new BroadcastReceiver() {

       @Override
       public void onReceive(Context context, Intent intent) {
           Log.d(TAG, "Sync started!");
           Toast.makeText(getApplicationContext(), "Sync started...", Toast.LENGTH_SHORT).show();
       }
   };
}

MyIPContentProvider

public class MyIPContentProvider extends ContentProvider {

public static final int IP_DATA=1;
private static final String AUTHORITY="sample.map.com.ipsyncadapter";
private static final String TABLE_IP_DATA="ip_data";
public static final Uri CONTENT_URI=Uri.parse("content://" + AUTHORITY + '/' + TABLE_IP_DATA);
private static final UriMatcher URI_MATCHER= new UriMatcher(UriMatcher.NO_MATCH);

static
{
    URI_MATCHER.addURI(AUTHORITY,TABLE_IP_DATA,IP_DATA);
}

private IpDataDBHelper myDB;

@Override
public boolean onCreate() {
    myDB=new IpDataDBHelper(getContext(),null,null,1);
    return false;
}

@Nullable
@Override
public Cursor query(Uri uri, String[] strings, String s, String[] strings1, String s1) {
    int uriType=URI_MATCHER.match(uri);
    Cursor cursor=null;
    switch (uriType)
    {
        case IP_DATA:
            cursor=myDB.getAllIpData();
            break;
        default:
            throw new IllegalArgumentException("UNKNOWN URL");
    }
    cursor.setNotificationUri(getContext().getContentResolver(), uri);
    return cursor;
}

@Nullable
@Override
public String getType(Uri uri) {
    return null;
}

@Nullable
@Override
public Uri insert(Uri uri, ContentValues contentValues) {
    int uriType=URI_MATCHER.match(uri);
    long id=0;
    switch (uriType)
    {
        case IP_DATA:
            id=myDB.AddIPData(contentValues);
            break;
        default:
            throw new IllegalArgumentException("UNKNOWN URI :" +uri);
    }
    getContext().getContentResolver().notifyChange(uri,null);
    return Uri.parse(contentValues + "/" + id);
}

@Override
public int delete(Uri uri, String s, String[] strings) {
    int uriType=URI_MATCHER.match(uri);
    int rowsDeleted=0;

    switch (uriType)
    {
        case IP_DATA:
            rowsDeleted=myDB.deleteAllIpData();
            break;
        default:
            throw new IllegalArgumentException("UNKNOWN URI :" +uri);
    }
    getContext().getContentResolver().notifyChange(uri,null);
    return rowsDeleted;
}

@Override
public int update(Uri uri, ContentValues contentValues, String s, String[] strings) {
    return 0;
}

}

SyncAdapter

public class SyncAdapter extends AbstractThreadedSyncAdapter {
ContentResolver mContentResolver;
Context mContext;
public static final String SYNC_STARTED="Sync Started";
public static final String SYNC_FINISHED="Sync Finished";
private static final String TAG=SyncAdapter.class.getCanonicalName();
public SharedPreferences mSharedPreferences;

public SyncAdapter(Context context, boolean autoInitialize) {
    super(context, autoInitialize);
    this.mContext=context;
    mContentResolver=context.getContentResolver();
    Log.i("SyncAdapter","SyncAdapter");
}

@Override
public void onPerformSync(Account account, Bundle bundle, String s, ContentProviderClient contentProviderClient, SyncResult syncResult) {

    Intent intent = new Intent(SYNC_STARTED);
    mContext.sendBroadcast(intent);

    Log.i(TAG, "onPerformSync");

    intent = new Intent(SYNC_FINISHED);
    mContext.sendBroadcast(intent);
    mSharedPreferences =mContext.getSharedPreferences("MyIp",0);
    SharedPreferences.Editor editor=mSharedPreferences.edit();

    mContentResolver.delete(MyIPContentProvider.CONTENT_URI,null,null);

    String data="";

    try {
        URL url =new URL("https://freegeoip.net/json/");
        Log.d(TAG, "URL :"+url);
        HttpURLConnection connection=(HttpURLConnection)url.openConnection();
        Log.d(TAG,"Connection :"+connection);
        connection.connect();
        Log.d(TAG,"Connection 1:"+connection);
        InputStream inputStream=connection.getInputStream();
        data=getInputData(inputStream);
        Log.d(TAG,"Data :"+data);

        if (data != null || !data.equals("null")) {
            JSONObject jsonObject = new JSONObject(data);
String ipa = jsonObject.getString("ip");
String country_code = jsonObject.getString("country_code");
String country_name = jsonObject.getString("country_name");
String region_code=jsonObject.getString("region_code");
String region_name=jsonObject.getString("region_name");
String zip_code=jsonObject.getString("zip_code");
String time_zone=jsonObject.getString("time_zone");
String metro_code=jsonObject.getString("metro_code");

String city = jsonObject.getString("city");
String latitude = jsonObject.getString("latitude");
String longitude = jsonObject.getString("longitude");
/* ContentValues values = new ContentValues();
values.put("ip", ipa);
values.put("country_code", country_code);
values.put("country_name", country_name);
values.put("city", city);
values.put("latitude", latitude);
values.put("longitude", longitude);*/
//Using cursor adapter for results.
//mContentResolver.insert(MyIPContentProvider.CONTENT_URI, values);

//Using Shared preference for results.
editor.putString("ipAdr",ipa);
editor.putString("CCode",country_code);
editor.putString("CName",country_name);
editor.putString("City",city);
editor.putString("Latitude",latitude);
editor.putString("Longitude",longitude);
editor.commit();

}
}catch(Exception e){
e.printStackTrace();
}

}

private String getInputData(InputStream inputStream) throws IOException {
StringBuilder builder=new StringBuilder();
BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(inputStream));
//String data=null;
/*Log.d(TAG,"Builder 2:"+ bufferedReader.readLine());
while ((data=bufferedReader.readLine())!= null);
{
builder.append(data);
Log.d(TAG,"Builder :"+data);
}
Log.d(TAG,"Builder 1 :"+data);
bufferedReader.close();*/
String data=bufferedReader.readLine();
bufferedReader.close();
return data.toString();
}

}

SyncService

public class SyncService extends Service {
private static SyncAdapter syncAdapter=null;
private static final Object syncAdapterLock=new Object();

@Override
public void onCreate() {
    synchronized (syncAdapterLock)
    {
        if(syncAdapter==null)
        {
            syncAdapter =new SyncAdapter(getApplicationContext(),true);
        }
    }
}

@Nullable
@Override
public IBinder onBind(Intent intent) {
    return syncAdapter.getSyncAdapterBinder();
}

}

Feedback about page:

Feedback:
Optional: your email if you want me to get back to you:


SyncAdapter with periodically do sync of data:
* Sync adapter with every min requesting value from server.

Table Of Contents
2 Gradle
5 Intent
17 Service
19 WebView
31 SQLite
35 Glide
37 Dialog
38 ACRA
44 Handler
53 Toast
63 Menu
65 Picasso
70 Volley
71 Widgets
78 Realm
90 Spinner
95 OkHttp
108 TextView
109 ListView
111 Loader
118 Xposed
119 Security
121 ImageView
123 Doze Mode
130 Drawables
131 Colors
134 Fresco
139 AdMob
145 Keyboard
146 Button
150 EditText
155 Vk SDK
163 ExoPlayer
169 XMPP
175 OpenCV
177 Threads
184 ORMLite
186 TabLayout
190 LruCache
192 Zip files
194 Fastlane
199 FileIO
202 Moshi
210 VideoView
216 Paint
218 ProGuard
226 CleverTap
228 ADB shell
229 Ping ICMP
230 AIDL
234 Context
240 JCodec
242 Okio
249 FuseView
254 Looper
259 SyncAdapter with periodically do sync of data
261 Fastjson
263 Jackson
267 Smartcard