Reimplemented API Provider
To try to fix NullPointerException on mApi reported in Play Store
This commit is contained in:
		| @@ -18,12 +18,12 @@ | ||||
| apply plugin: 'com.android.application' | ||||
|  | ||||
| android { | ||||
|     compileSdkVersion 30 | ||||
|     compileSdkVersion 31 | ||||
|  | ||||
|     defaultConfig { | ||||
|         applicationId "it.danieleverducci.nextcloudmaps" | ||||
|         minSdkVersion 23 | ||||
|         targetSdkVersion 30 | ||||
|         targetSdkVersion 31 | ||||
|         versionCode 6 | ||||
|         versionName "0.3.4" | ||||
|  | ||||
| @@ -54,7 +54,7 @@ repositories { | ||||
| dependencies { | ||||
|     implementation fileTree(dir: "libs", include: ["*.jar"]) | ||||
|  | ||||
|     implementation 'com.android.support:design:30.0.1' | ||||
|     implementation 'com.android.support:design:31.0.0' | ||||
|     implementation 'androidx.appcompat:appcompat:1.3.1' | ||||
|     implementation 'androidx.recyclerview:recyclerview:1.2.1' | ||||
|     implementation "androidx.cardview:cardview:1.0.0" | ||||
| @@ -70,7 +70,7 @@ dependencies { | ||||
|     implementation 'com.squareup.retrofit2:converter-gson:2.6.1' | ||||
|  | ||||
|     // Nextcloud SSO | ||||
|     implementation "com.github.nextcloud:Android-SingleSignOn:0.5.6" | ||||
|     implementation "com.github.nextcloud:Android-SingleSignOn:0.6.1" | ||||
|  | ||||
|     // OSMDroid | ||||
|     implementation 'org.osmdroid:osmdroid-android:6.1.10' | ||||
|   | ||||
| @@ -35,21 +35,24 @@ | ||||
|         android:supportsRtl="true" | ||||
|         android:theme="@style/AppTheme"> | ||||
|  | ||||
|         <activity android:name=".activity.login.LoginActivity"> | ||||
|         <activity android:name=".activity.login.LoginActivity" | ||||
|             android:exported="true"> | ||||
|             <intent-filter> | ||||
|                 <action android:name="android.intent.action.MAIN" /> | ||||
|                 <category android:name="android.intent.category.LAUNCHER" /> | ||||
|             </intent-filter> | ||||
|         </activity> | ||||
|  | ||||
|         <activity android:name=".activity.main.MainActivity"> | ||||
|         <activity android:name=".activity.main.MainActivity" | ||||
|             android:exported="true"> | ||||
|             <intent-filter> | ||||
|                 <action android:name="android.intent.action.VIEW" /> | ||||
|             </intent-filter> | ||||
|         </activity> | ||||
|  | ||||
|         <activity | ||||
|             android:name=".activity.detail.GeofavoriteDetailActivity"> | ||||
|             android:name=".activity.detail.GeofavoriteDetailActivity" | ||||
|             android:exported="true"> | ||||
|             <!-- standard "geo" scheme --> | ||||
|             <intent-filter> | ||||
|                 <action android:name="android.intent.action.VIEW"/> | ||||
| @@ -89,6 +92,7 @@ | ||||
|         </activity> | ||||
|  | ||||
|         <activity android:name=".activity.mappicker.MapPickerActivity" | ||||
|             android:exported="true" | ||||
|             android:theme="@style/AppTheme"> | ||||
|             <intent-filter> | ||||
|                 <action android:name="android.intent.action.VIEW" /> | ||||
|   | ||||
| @@ -119,7 +119,7 @@ public class GeofavoriteDetailActivity extends NextcloudMapsStyledActivity imple | ||||
|         }); | ||||
|  | ||||
|         mViewModel = new ViewModelProvider(this).get(GeofavoriteDetailActivityViewModel.class); | ||||
|         mViewModel.init(); | ||||
|         mViewModel.init(getApplicationContext()); | ||||
|         mViewModel.getCategories().observe(this, new Observer<HashSet<String>>() { | ||||
|             @Override | ||||
|             public void onChanged(HashSet<String> categories) { | ||||
|   | ||||
| @@ -1,5 +1,7 @@ | ||||
| package it.danieleverducci.nextcloudmaps.activity.detail; | ||||
|  | ||||
| import android.content.Context; | ||||
|  | ||||
| import androidx.lifecycle.LiveData; | ||||
| import androidx.lifecycle.MutableLiveData; | ||||
| import androidx.lifecycle.ViewModel; | ||||
| @@ -14,8 +16,8 @@ import it.danieleverducci.nextcloudmaps.repository.GeofavoriteRepository; | ||||
| public class GeofavoriteDetailActivityViewModel extends ViewModel { | ||||
|     private GeofavoriteRepository mRepo; | ||||
|  | ||||
|     public void init() { | ||||
|         mRepo = GeofavoriteRepository.getInstance(); | ||||
|     public void init(Context applicationContext) { | ||||
|         mRepo = GeofavoriteRepository.getInstance(applicationContext); | ||||
|     } | ||||
|  | ||||
|     public Geofavorite getGeofavorite(int id) { | ||||
|   | ||||
| @@ -41,11 +41,11 @@ import com.nextcloud.android.sso.ui.UiExceptionManager; | ||||
| import it.danieleverducci.nextcloudmaps.R; | ||||
| import it.danieleverducci.nextcloudmaps.activity.NextcloudMapsStyledActivity; | ||||
| import it.danieleverducci.nextcloudmaps.activity.main.MainActivity; | ||||
| import it.danieleverducci.nextcloudmaps.api.API; | ||||
| import it.danieleverducci.nextcloudmaps.api.ApiProvider; | ||||
|  | ||||
| public class LoginActivity extends NextcloudMapsStyledActivity { | ||||
|  | ||||
|     protected ApiProvider mApi; | ||||
|     protected ProgressBar progress; | ||||
|     protected Button button; | ||||
|  | ||||
| @@ -115,9 +115,6 @@ public class LoginActivity extends NextcloudMapsStyledActivity { | ||||
|     } | ||||
|  | ||||
|     private void accountAccessDone() { | ||||
|         Context l_context = getApplicationContext(); | ||||
|         mApi = new ApiProvider(l_context); | ||||
|  | ||||
|         Intent intent = new Intent(LoginActivity.this, MainActivity.class); | ||||
|         startActivity(intent); | ||||
|  | ||||
|   | ||||
| @@ -58,6 +58,7 @@ import it.danieleverducci.nextcloudmaps.activity.login.LoginActivity; | ||||
| import it.danieleverducci.nextcloudmaps.activity.main.NavigationAdapter.NavigationItem; | ||||
| import it.danieleverducci.nextcloudmaps.activity.main.SortingOrderDialogFragment.OnSortingOrderListener; | ||||
| import it.danieleverducci.nextcloudmaps.activity.mappicker.MapPickerActivity; | ||||
| import it.danieleverducci.nextcloudmaps.api.ApiProvider; | ||||
| import it.danieleverducci.nextcloudmaps.model.Geofavorite; | ||||
| import it.danieleverducci.nextcloudmaps.utils.GeoUriParser; | ||||
| import it.danieleverducci.nextcloudmaps.utils.IntentGenerator; | ||||
| @@ -140,7 +141,7 @@ public class MainActivity extends NextcloudMapsStyledActivity implements OnSorti | ||||
|  | ||||
|  | ||||
|         mMainActivityViewModel = new ViewModelProvider(this).get(MainActivityViewModel.class); | ||||
|         mMainActivityViewModel.init(); | ||||
|         mMainActivityViewModel.init(getApplicationContext()); | ||||
|         mMainActivityViewModel.getIsUpdating().observe(this, new Observer<Boolean>() { | ||||
|             @Override | ||||
|             public void onChanged(@Nullable Boolean aBoolean) { | ||||
| @@ -155,7 +156,7 @@ public class MainActivity extends NextcloudMapsStyledActivity implements OnSorti | ||||
|         mMainActivityViewModel.getOnFinished().observe(this, new Observer<Boolean>() { | ||||
|             @Override | ||||
|             public void onChanged(@Nullable Boolean success) { | ||||
|                 if(!success){ | ||||
|                 if(success == null || !success){ | ||||
|                     Toast.makeText(MainActivity.this, R.string.list_geofavorite_connection_error, Toast.LENGTH_LONG).show(); | ||||
|                 } | ||||
|             } | ||||
| @@ -297,9 +298,11 @@ public class MainActivity extends NextcloudMapsStyledActivity implements OnSorti | ||||
|     } | ||||
|  | ||||
|     private void switch_account() { | ||||
|         ApiProvider.logout(); | ||||
|         SingleAccountHelper.setCurrentAccount(this, null); | ||||
|         Intent intent = new Intent(MainActivity.this, LoginActivity.class); | ||||
|         startActivity(intent); | ||||
|         finish(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|   | ||||
| @@ -1,5 +1,7 @@ | ||||
| package it.danieleverducci.nextcloudmaps.activity.main; | ||||
|  | ||||
| import android.content.Context; | ||||
|  | ||||
| import androidx.lifecycle.LiveData; | ||||
| import androidx.lifecycle.MutableLiveData; | ||||
| import androidx.lifecycle.ViewModel; | ||||
| @@ -12,8 +14,8 @@ import it.danieleverducci.nextcloudmaps.repository.GeofavoriteRepository; | ||||
| public class MainActivityViewModel extends ViewModel { | ||||
|     private GeofavoriteRepository mRepo; | ||||
|  | ||||
|     public void init() { | ||||
|         mRepo = GeofavoriteRepository.getInstance(); | ||||
|     public void init(Context applicationContext) { | ||||
|         mRepo = GeofavoriteRepository.getInstance(applicationContext); | ||||
|     } | ||||
|  | ||||
|     public LiveData<List<Geofavorite>> getGeofavorites(){ | ||||
|   | ||||
| @@ -24,6 +24,7 @@ import android.content.Context; | ||||
| import android.util.Log; | ||||
|  | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.annotation.Nullable; | ||||
|  | ||||
| import com.google.gson.GsonBuilder; | ||||
| import com.nextcloud.android.sso.api.NextcloudAPI; | ||||
| @@ -35,47 +36,27 @@ import com.nextcloud.android.sso.model.SingleSignOnAccount; | ||||
| import retrofit2.NextcloudRetrofitApiBuilder; | ||||
|  | ||||
| public class ApiProvider { | ||||
|     private final String TAG = ApiProvider.class.getCanonicalName(); | ||||
|     private static final String TAG = ApiProvider.class.getCanonicalName(); | ||||
|  | ||||
|     @NonNull | ||||
|     protected Context context; | ||||
|     protected static API mApi; | ||||
|  | ||||
|     protected static String ssoAccountName; | ||||
|     @Nullable | ||||
|     public static API getAPI(Context context) { | ||||
|         if (mApi == null) { | ||||
|             try { | ||||
|                 SingleSignOnAccount ssoAccount = SingleAccountHelper.getCurrentSingleSignOnAccount(context); | ||||
|                 NextcloudAPI nextcloudAPI = new NextcloudAPI(context, ssoAccount, new GsonBuilder().create()); | ||||
|  | ||||
|     public ApiProvider(Context context) { | ||||
|         this.context = context; | ||||
|         initSsoApi(new NextcloudAPI.ApiConnectedListener() { | ||||
|             @Override | ||||
|             public void onConnected() { | ||||
|                 Log.d(TAG, "Connected to Nextcloud instance"); | ||||
|                 mApi = new NextcloudRetrofitApiBuilder(nextcloudAPI, API.mApiEndpoint).create(API.class); | ||||
|             } catch (NextcloudFilesAppAccountNotFoundException | NoCurrentAccountSelectedException e) { | ||||
|                 Log.d(TAG, "setAccout() called with: ex = [" + e + "]"); | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public void onError(Exception ex) { | ||||
|                 Log.d(TAG, "Unable to connect to Nextcloud instance: " + ex.toString()); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     public void initSsoApi(final NextcloudAPI.ApiConnectedListener callback) { | ||||
|         try { | ||||
|             SingleSignOnAccount ssoAccount = SingleAccountHelper.getCurrentSingleSignOnAccount(context); | ||||
|             NextcloudAPI nextcloudAPI = new NextcloudAPI(context, ssoAccount, new GsonBuilder().create(), callback); | ||||
|  | ||||
|             ssoAccountName = ssoAccount.name; | ||||
|             mApi = new NextcloudRetrofitApiBuilder(nextcloudAPI, API.mApiEndpoint).create(API.class); | ||||
|         } catch (NextcloudFilesAppAccountNotFoundException | NoCurrentAccountSelectedException e) { | ||||
|             Log.d(TAG, "setAccout() called with: ex = [" + e + "]"); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public static API getAPI() { | ||||
|         return mApi; | ||||
|     } | ||||
|  | ||||
|     public static String getAccountName() { | ||||
|         return ssoAccountName; | ||||
|     public static void logout() { | ||||
|         mApi = null; | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -1,9 +1,9 @@ | ||||
| package it.danieleverducci.nextcloudmaps.repository; | ||||
|  | ||||
| import android.content.Context; | ||||
| import android.util.Log; | ||||
|  | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.appcompat.app.AppCompatActivity; | ||||
| import androidx.lifecycle.MutableLiveData; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| @@ -29,9 +29,15 @@ public class GeofavoriteRepository { | ||||
|     private MutableLiveData<Boolean> mIsUpdating = new MutableLiveData<>(false); | ||||
|     private SingleLiveEvent<Boolean> mOnFinished = new SingleLiveEvent<>(); | ||||
|  | ||||
|     public static GeofavoriteRepository getInstance() { | ||||
|     private Context applicationContext; | ||||
|  | ||||
|     public GeofavoriteRepository(Context applicationContext) { | ||||
|         this.applicationContext = applicationContext; | ||||
|     } | ||||
|  | ||||
|     public static GeofavoriteRepository getInstance(Context applicationContext) { | ||||
|         if(instance == null){ | ||||
|             instance = new GeofavoriteRepository(); | ||||
|             instance = new GeofavoriteRepository(applicationContext); | ||||
|         } | ||||
|         return instance; | ||||
|     } | ||||
| @@ -59,7 +65,7 @@ public class GeofavoriteRepository { | ||||
|     public void updateGeofavorites() { | ||||
|         mIsUpdating.postValue(true); | ||||
|         // Obtain geofavorites | ||||
|         Call<List<Geofavorite>> call = ApiProvider.getAPI().getGeofavorites(); | ||||
|         Call<List<Geofavorite>> call = ApiProvider.getAPI(this.applicationContext).getGeofavorites(); | ||||
|         call.enqueue(new Callback<List<Geofavorite>>() { | ||||
|             @Override | ||||
|             public void onResponse(@NonNull Call<List<Geofavorite>> call, @NonNull Response<List<Geofavorite>> response) { | ||||
| @@ -94,10 +100,10 @@ public class GeofavoriteRepository { | ||||
|         Call<Geofavorite> call; | ||||
|         if (geofav.getId() == 0) { | ||||
|             // New geofavorite | ||||
|             call = ApiProvider.getAPI().createGeofavorite(geofav); | ||||
|             call = ApiProvider.getAPI(this.applicationContext).createGeofavorite(geofav); | ||||
|         } else { | ||||
|             // Update existing geofavorite | ||||
|             call = ApiProvider.getAPI().updateGeofavorite(geofav.getId(), geofav); | ||||
|             call = ApiProvider.getAPI(this.applicationContext).updateGeofavorite(geofav.getId(), geofav); | ||||
|         } | ||||
|         call.enqueue(new Callback<Geofavorite>() { | ||||
|             @Override | ||||
| @@ -129,7 +135,7 @@ public class GeofavoriteRepository { | ||||
|     public void deleteGeofavorite(Geofavorite geofav) { | ||||
|         mIsUpdating.postValue(true); | ||||
|         // Delete Geofavorite | ||||
|         Call<Geofavorite> call = ApiProvider.getAPI().deleteGeofavorite(geofav.getId()); | ||||
|         Call<Geofavorite> call = ApiProvider.getAPI(this.applicationContext).deleteGeofavorite(geofav.getId()); | ||||
|         call.enqueue(new Callback<Geofavorite>() { | ||||
|             @Override | ||||
|             public void onResponse(Call<Geofavorite> call, Response<Geofavorite> response) { | ||||
|   | ||||
| @@ -25,7 +25,7 @@ buildscript { | ||||
|         jcenter() | ||||
|     } | ||||
|     dependencies { | ||||
|         classpath 'com.android.tools.build:gradle:4.2.2' | ||||
|         classpath 'com.android.tools.build:gradle:7.1.1' | ||||
|  | ||||
|         // NOTE: Do not place your application dependencies here; they belong | ||||
|         // in the individual module build.gradle files | ||||
|   | ||||
							
								
								
									
										23
									
								
								gradle/wrapper/gradle-wrapper.properties
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										23
									
								
								gradle/wrapper/gradle-wrapper.properties
									
									
									
									
										vendored
									
									
								
							| @@ -1,23 +1,6 @@ | ||||
| # | ||||
| # Nextcloud Geofavorites for Android | ||||
| # | ||||
| # This program is free software: you can redistribute it and/or modify | ||||
| # it under the terms of the GNU General Public License as published by | ||||
| # the Free Software Foundation, either version 3 of the License, or | ||||
| # (at your option) any later version. | ||||
| # | ||||
| # This program is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| # GNU General Public License for more details. | ||||
| # | ||||
| # You should have received a copy of the GNU General Public License | ||||
| # along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
| # | ||||
|  | ||||
| #Mon Oct 05 23:27:18 ART 2020 | ||||
| #Sun Feb 20 08:50:37 CET 2022 | ||||
| distributionBase=GRADLE_USER_HOME | ||||
| distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip | ||||
| distributionPath=wrapper/dists | ||||
| zipStoreBase=GRADLE_USER_HOME | ||||
| zipStorePath=wrapper/dists | ||||
| distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip | ||||
| zipStoreBase=GRADLE_USER_HOME | ||||
|   | ||||
		Reference in New Issue
	
	Block a user