/*
* Copyright 2015. Appsi Mobile
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.appsimobile.appsii.module.apps;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Handler;
import java.util.ArrayList;
import java.util.List;
import java.util.WeakHashMap;
/**
* Handles automatic loading and reloading of the app-tags.
* Simply registering a listener will trigger the initial load.
* <p/>
* The listener will be called whenever the the data is changed again
* Created by nick on 23/08/14.
*/
public class AppTagUtils {
/**
* The tags still need to be loaded
*/
static final int STATUS_NEEDS_LOAD = 0;
private static final int STATUS_LOADING = 1;
private static final int STATUS_READY = 2;
private static AppTagUtils sInstance;
final Context mContext;
private final Handler mHandler;
int mStatus = STATUS_NEEDS_LOAD;
final ContentObserver mContentObserver;
private final ArrayList<AppTag> mAppTags = new ArrayList<>(6);
private final WeakHashMap<AppTagListener, Void> mListeners = new WeakHashMap<>();
private AppTagUtils(Context context) {
mContext = context;
mHandler = new Handler();
mContentObserver = new ContentObserver(mHandler) {
@Override
public void onChange(boolean selfChange) {
onChange(selfChange, null);
}
@Override
public void onChange(boolean selfChange, Uri uri) {
mStatus = STATUS_NEEDS_LOAD;
ensureLoaded();
}
};
mContext.getContentResolver().registerContentObserver(
AppsContract.TagColumns.CONTENT_URI, true, mContentObserver);
}
static List<AppTag> loadTagsBlocking(Context context) {
Uri uri = AppsContract.TagColumns.CONTENT_URI;
ContentResolver contentResolver = context.getContentResolver();
Cursor cursor =
contentResolver.query(uri, AppTagQuery.PROJECTION, null, null, AppTagQuery.ORDER);
int count = cursor.getCount();
List<AppTag> result = new ArrayList<>(count);
while (cursor.moveToNext()) {
long id = cursor.getLong(AppTagQuery._ID);
boolean defaultExpanded = cursor.getInt(AppTagQuery.DEFAULT_EXPANDED) == 1;
String name = cursor.getString(AppTagQuery.NAME);
int position = cursor.getInt(AppTagQuery.POSITION);
int columnCount = cursor.getInt(AppTagQuery.COLUMN_COUNT);
int tagType = cursor.getInt(AppTagQuery.TAG_TYPE);
boolean visible = cursor.getInt(AppTagQuery.VISIBLE) == 1;
AppTag tag = new AppTag(id, name, position, defaultExpanded,
visible, columnCount, tagType);
result.add(tag);
}
cursor.close();
return result;
}
public static AppTagUtils getInstance(Context context) {
if (sInstance == null) {
sInstance = new AppTagUtils(context.getApplicationContext());
}
return sInstance;
}
public static long insertTagBlocking(Context context, String name, int position,
boolean defaultExpanded, boolean visible) {
Uri uri = AppsContract.TagColumns.CONTENT_URI;
ContentResolver contentResolver = context.getContentResolver();
ContentValues contentValues = new ContentValues();
contentValues.put(AppsContract.TagColumns.NAME, name);
contentValues.put(AppsContract.TagColumns.POSITION, position);
contentValues.put(AppsContract.TagColumns.DEFAULT_EXPANDED, defaultExpanded ? 1 : 0);
contentValues.put(AppsContract.TagColumns.VISIBLE, visible ? 1 : 0);
Uri result = contentResolver.insert(uri, contentValues);
return ContentUris.parseId(result);
}
void ensureLoaded() {
// when we are already loading, ignore the request
if (mStatus > STATUS_NEEDS_LOAD) return;
mStatus = STATUS_LOADING;
AsyncTask<Void, Void, List<AppTag>> task = new AsyncTask<Void, Void, List<AppTag>>() {
@Override
protected List<AppTag> doInBackground(Void... params) {
return loadTagsBlocking(mContext);
}
@Override
protected void onPostExecute(List<AppTag> appTags) {
onAppTagsLoaded(appTags);
}
};
task.execute();
}
void onAppTagsLoaded(List<AppTag> appTags) {
mStatus = STATUS_READY;
mAppTags.clear();
mAppTags.addAll(appTags);
notifyAppTagsLoaded();
}
private void notifyAppTagsLoaded() {
for (AppTagListener l : mListeners.keySet()) {
l.onTagsChanged(mAppTags);
}
}
public void unregisterAppTagListener(AppTagListener listener) {
mListeners.remove(listener);
}
public List<AppTag> registerAppTagListener(AppTagListener listener) {
mListeners.put(listener, null);
ensureLoaded();
return mAppTags;
}
public interface AppTagListener {
void onTagsChanged(ArrayList<AppTag> appTags);
}
}