/*
* Copyright (C) 2012 Simon Robinson
*
* This file is part of Com-Me.
*
* Com-Me is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* Com-Me 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 Lesser General
* Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with Com-Me.
* If not, see <http://www.gnu.org/licenses/>.
*/
package ac.robinson.mediatablet;
import java.io.File;
import ac.robinson.mediatablet.activity.AddUserActivity;
import ac.robinson.mediatablet.activity.HomesteadBrowserActivity;
import ac.robinson.mediatablet.activity.MediaBrowserActivity;
import ac.robinson.mediatablet.activity.PreferencesActivity;
import ac.robinson.mediatablet.importing.ImportedFileParser;
import ac.robinson.mediatablet.provider.MediaItem;
import ac.robinson.mediatablet.provider.PersonItem;
import ac.robinson.mediautilities.FrameMediaContainer;
import ac.robinson.mediautilities.MediaUtilities;
import ac.robinson.util.DebugUtilities;
import ac.robinson.util.UIUtilities;
import ac.robinson.util.ViewServer;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Message;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.Window;
public abstract class MediaTabletActivity extends Activity {
abstract protected void loadPreferences(SharedPreferences mediaTabletSettings);
abstract protected String getCurrentPersonId();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (MediaTablet.DEBUG) {
ViewServer.get(this).addWindow(this);
}
// for API < 11, buttons are in the main screen, so hide the title/action bar
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
}
UIUtilities.setPixelDithering(getWindow());
checkDirectoriesExist();
SharedPreferences panoramaSettings = getSharedPreferences(MediaTablet.APPLICATION_NAME, Context.MODE_PRIVATE);
MediaTablet.ADMINISTRATOR_PASSWORD = panoramaSettings.getString(getString(R.string.key_administrator_password),
MediaTablet.ADMINISTRATOR_PASSWORD);
}
@Override
protected void onStart() {
loadAllPreferences();
super.onStart();
}
@Override
protected void onResume() {
super.onResume();
if (MediaTablet.DEBUG) {
ViewServer.get(this).setFocusedWindow(this);
}
((MediaTabletApplication) this.getApplication()).registerActivityHandle(this);
}
@Override
protected void onPause() {
super.onPause();
((MediaTabletApplication) this.getApplication()).removeActivityHandle(this);
}
@Override
protected void onDestroy() {
if (MediaTablet.DEBUG) {
ViewServer.get(this).removeWindow(this);
}
super.onDestroy();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.preferences, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
Intent intent = new Intent(MediaTabletActivity.this, HomesteadBrowserActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
return true;
case R.id.menu_preferences:
final Intent preferencesIntent = new Intent(MediaTabletActivity.this, PreferencesActivity.class);
startActivityForResult(preferencesIntent, R.id.intent_preferences);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent resultIntent) {
switch (requestCode) {
case R.id.intent_preferences:
loadAllPreferences();
break;
default:
super.onActivityResult(requestCode, resultCode, resultIntent);
}
}
private void loadAllPreferences() {
SharedPreferences mediaTabletSettings = PreferenceManager.getDefaultSharedPreferences(MediaTabletActivity.this);
// bluetooth observer
configureBluetoothObserver(mediaTabletSettings, getResources());
// other activity-specific preferences
loadPreferences(mediaTabletSettings);
}
protected void configureBluetoothObserver(SharedPreferences mediaTabletSettings, Resources res) {
boolean watchForFiles = res.getBoolean(R.bool.default_watch_for_files);
try {
watchForFiles = mediaTabletSettings.getBoolean(getString(R.string.key_watch_for_files), watchForFiles);
} catch (Exception e) {
watchForFiles = res.getBoolean(R.bool.default_watch_for_files);
}
if (watchForFiles) {
// file changes are handled in startWatchingBluetooth();
((MediaTabletApplication) getApplication()).startWatchingBluetooth();
} else {
((MediaTabletApplication) getApplication()).stopWatchingBluetooth();
}
}
public void checkDirectoriesExist() {
// nothing will work, and previously saved files will not load
if (MediaTablet.DIRECTORY_STORAGE == null) {
// if we're not in the main activity, quit everything else and launch the homestead browser to exit
boolean clearTop = false;
if (!((Object) MediaTabletActivity.this instanceof HomesteadBrowserActivity)) {
clearTop = true;
} else if (((HomesteadBrowserActivity) MediaTabletActivity.this).isInEditMode()) {
clearTop = true;
}
if (clearTop) {
Intent homeIntent = new Intent(this, HomesteadBrowserActivity.class);
homeIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(homeIntent);
Log.d(DebugUtilities.getLogTag(this), "Couldn't open storage directory - clearing top to exit");
return;
}
SharedPreferences mediaTabletSettings = getSharedPreferences(MediaTablet.APPLICATION_NAME,
Context.MODE_PRIVATE);
final String storageKey = getString(R.string.key_use_external_storage);
if (mediaTabletSettings.contains(storageKey)) {
if (mediaTabletSettings.getBoolean(storageKey, true)) { // defValue is irrelevant, we know value exists
if (!isFinishing()) {
UIUtilities.showToast(MediaTabletActivity.this, R.string.error_opening_media_content_sd, true);
}
Log.d(DebugUtilities.getLogTag(this), "Couldn't open storage directory (SD card) - exiting");
finish();
return;
}
}
if (!isFinishing()) {
UIUtilities.showToast(MediaTabletActivity.this, R.string.error_opening_media_content, true);
}
Log.d(DebugUtilities.getLogTag(this), "Couldn't open storage directory - exiting");
finish();
return;
} else {
// the UNKNOWN_PERSON_ID directory is where all public media is transferred to - it must exist
if (!PersonItem.getStorageDirectory(PersonItem.UNKNOWN_PERSON_ID).exists()) {
if (!PersonItem.getStorageDirectory(PersonItem.UNKNOWN_PERSON_ID).mkdirs()) {
Log.d(DebugUtilities.getLogTag(this), "Unable to create public directory");
}
}
}
// thumbnail cache won't work, but not really fatal (thumbnails will be loaded into memory on demand)
if (MediaTablet.DIRECTORY_THUMBS == null) {
Log.d(DebugUtilities.getLogTag(this), "Thumbnail directory not found");
}
// external narrative sending (Bluetooth etc) may not work, but not really fatal (will warn on export)
if (MediaTablet.DIRECTORY_TEMP == null) {
Log.d(DebugUtilities.getLogTag(this), "Temporary directory not found - will warn before export");
}
// bluetooth directory availability may have changed if we're calling from an SD card availability notification
configureBluetoothObserver(PreferenceManager.getDefaultSharedPreferences(MediaTabletActivity.this),
getResources());
}
public void processIncomingFiles(Message msg) {
// deal with messages from the BluetoothObserver
Bundle fileData = msg.peekData();
if (fileData == null) {
return; // error - no parameters passed
}
String importedFileName = fileData.getString(MediaUtilities.KEY_FILE_NAME);
if (importedFileName == null) {
return; // error - no filename
}
// get the imported file object
final File importedFile = new File(importedFileName);
if (!importedFile.canRead() || !importedFile.canWrite()) {
importedFile.delete(); // error - probably won't work, but might
// as well try; doesn't throw, so is okay
return;
}
final String mediaParent = getCurrentPersonId();
final int mediaVisibility = PersonItem.UNKNOWN_PERSON_ID.equals(mediaParent) ? MediaItem.MEDIA_PUBLIC
: MediaItem.MEDIA_PRIVATE;
switch (msg.what) {
case MediaUtilities.MSG_RECEIVED_IMPORT_FILE:
ImportedFileParser.importMediaItem(getContentResolver(), mediaParent, importedFile, mediaVisibility,
true);
break;
case MediaUtilities.MSG_RECEIVED_SMIL_FILE:
FrameMediaContainer currentSmilFile = new FrameMediaContainer(importedFile.getAbsolutePath(),
mediaVisibility); // hacky - using frameId for filename and frameSequenceId for visibility
currentSmilFile.mParentId = mediaParent; // again, hacky, but it works
new ImportSmilTask().execute(new FrameMediaContainer[] { currentSmilFile });
break;
case MediaUtilities.MSG_RECEIVED_HTML_FILE:
UIUtilities.showToast(MediaTabletActivity.this, R.string.html_feature_coming_soon);
importedFile.delete();
// TODO: this
break;
}
}
private class ImportSmilTask extends AsyncTask<FrameMediaContainer, Void, Void> {
@Override
protected Void doInBackground(FrameMediaContainer... smilParents) {
for (int i = 0, n = smilParents.length; i < n; i++) {
final FrameMediaContainer currentSmilFile = smilParents[i];
final File smilFile = new File(currentSmilFile.mFrameId);
ImportedFileParser.importSMILNarrative(getContentResolver(), smilFile, currentSmilFile.mParentId,
currentSmilFile.mFrameSequenceId);
smilFile.delete();
publishProgress();
}
return null;
}
@Override
protected void onProgressUpdate(Void... unused) {
}
@Override
protected void onPostExecute(Void unused) {
}
}
protected void viewPublicMedia() {
Intent publicMediaIntent = new Intent(MediaTabletActivity.this, MediaBrowserActivity.class);
startActivityForResult(publicMediaIntent, R.id.intent_media_browser);
}
protected void editPerson(String homesteadId, String personId) {
Intent addUserIntent = new Intent(MediaTabletActivity.this, AddUserActivity.class);
addUserIntent.putExtra(getString(R.string.extra_parent_id), homesteadId);
if (personId != null) {
addUserIntent.putExtra(getString(R.string.extra_internal_id), personId);
addUserIntent.putExtra(getString(R.string.extra_edit_mode), true);
}
startActivityForResult(addUserIntent, R.id.intent_add_user);
}
}