Prevent some crashes

This commit is contained in:
vanitasvitae 2015-05-14 00:18:45 +02:00
parent b1efbbdee0
commit 530bf2961f
5 changed files with 135 additions and 87 deletions

View file

@ -42,7 +42,7 @@ import java.util.ArrayList;
*/ */
public class MainActivity extends ActionBarActivity public class MainActivity extends ActionBarActivity
{ {
private ArrayList<Uri> sharedMedia; private ArrayList<String> sharedMedia;
private static String Tag = "stickToAlbum"; private static String Tag = "stickToAlbum";
SharedPreferences sharedPref = null; SharedPreferences sharedPref = null;
@ -53,13 +53,11 @@ public class MainActivity extends ActionBarActivity
setContentView(R.layout.activity_main); setContentView(R.layout.activity_main);
sharedPref = PreferenceManager.getDefaultSharedPreferences(this); sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
String appDirectoryPath = sharedPref.getString(SettingsActivity.KEY_PREF_APP_PATH, ""); if(sharedPref.getString(SettingsActivity.KEY_PREF_APP_PATH, "").isEmpty())
if(appDirectoryPath.isEmpty())
{ {
appDirectoryPath = resetAppDirectoryPath(); resetAppDirectoryPath();
} }
sharedMedia = new ArrayList<Uri>(); sharedMedia = new ArrayList<>();
Intent intent = getIntent(); Intent intent = getIntent();
String action = intent.getAction(); String action = intent.getAction();
@ -84,6 +82,9 @@ public class MainActivity extends ActionBarActivity
} }
} }
/**
* Handle first run
*/
protected void onResume() protected void onResume()
{ {
super.onResume(); super.onResume();
@ -103,40 +104,58 @@ public class MainActivity extends ActionBarActivity
}); });
firstRunDialog.setCancelable(false); firstRunDialog.setCancelable(false);
firstRunDialog.show(); firstRunDialog.show();
sharedPref.edit().putBoolean("firstrun", false).commit(); sharedPref.edit().putBoolean("firstrun", false).apply();
} }
} }
/** /**
* Handle one single file being shared with the application. * Handle one single file being shared with the application.
* Add the files Uri to the list of files to move and open the saveDialog. * Add the files Uri to the list of files to move and open the saveDialog.
* @param intent * @param intent Intent
*/ */
void handleSendSingleFile(Intent intent) { void handleSendSingleFile(Intent intent) {
Uri imageUri = intent.getParcelableExtra(Intent.EXTRA_STREAM); Uri imageUri = intent.getParcelableExtra(Intent.EXTRA_STREAM);
if (imageUri != null) { if (imageUri != null) {
sharedMedia.add(imageUri); String url = getRealPathFromURI(this, imageUri);
} if(url != null)
{
sharedMedia.add(url);
openSaveDialog(); openSaveDialog();
} }
else
{
handleUnsupportedMedia();
}
}
}
/** /**
* Handle multiple files being shared with the application. * Handle multiple files being shared with the application.
* Add the files Uris to the list of files to move and open the saveDialog. * Add the files Uris to the list of files to move and open the saveDialog.
* @param intent * @param intent Intent
*/ */
void handleSendMultipleFiles(Intent intent) { void handleSendMultipleFiles(Intent intent) {
ArrayList<Uri> imageUris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM); ArrayList<Uri> imageUris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
if (imageUris != null) { if (imageUris != null)
sharedMedia = imageUris; {
for(Uri u : imageUris)
{
String url = getRealPathFromURI(this, u);
if(url != null)
{
sharedMedia.add(url);
} }
openSaveDialog(); }
}
if(imageUris == null || imageUris.size()==0) handleUnsupportedMedia();
else openSaveDialog();
} }
/** /**
* Show Dialog to inform the user about the fact, that the feature he/she wants to use is not * Show Dialog to inform the user about the fact, that the feature he/she wants to use is not
* implemented * implemented
*/ */
@SuppressWarnings("unused")
void handleUnimplementedFeature() void handleUnimplementedFeature()
{ {
AlertDialog.Builder builder = new AlertDialog.Builder(this); AlertDialog.Builder builder = new AlertDialog.Builder(this);
@ -154,6 +173,43 @@ public class MainActivity extends ActionBarActivity
builder.show(); builder.show();
} }
void handleUnsupportedMedia()
{
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.dialog_title_unsupported_media);
builder.setMessage(R.string.dialog_content_unsupported_media);
builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
dialog.cancel();
finish();
}
});
builder.show();
}
void handleCouldNotWrite(String... urls)
{
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.dialog_title_write_failed);
String msg = getResources().getString(R.string.dialog_content_write_failed) + "\n\n";
for(String u : urls) msg = msg + u + "\n";
msg = msg.substring(0,msg.length()-1);
builder.setMessage(msg);
builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
dialog.cancel();
finish();
}
});
builder.show();
}
/** /**
* Open a Dialog that prompts the user to enter an album name. * Open a Dialog that prompts the user to enter an album name.
* Reopens dialog, if album name is empty. * Reopens dialog, if album name is empty.
@ -173,7 +229,7 @@ public class MainActivity extends ActionBarActivity
input.setInputType(InputType.TYPE_CLASS_TEXT); input.setInputType(InputType.TYPE_CLASS_TEXT);
ListView existingAlbums = (ListView) dialogView.findViewById(R.id.album_list); ListView existingAlbums = (ListView) dialogView.findViewById(R.id.album_list);
final ArrayList<String> directoryList = getFoldersOnDirectory(getAppDirectoryPath()); final ArrayList<String> directoryList = getFoldersOnDirectory(getAppDirectoryPath());
ArrayAdapter<String> adapter = new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, directoryList); ArrayAdapter<String> adapter = new ArrayAdapter<>(context, android.R.layout.simple_list_item_1, directoryList);
existingAlbums.setAdapter(adapter); existingAlbums.setAdapter(adapter);
existingAlbums.setOnItemClickListener(new AdapterView.OnItemClickListener() existingAlbums.setOnItemClickListener(new AdapterView.OnItemClickListener()
{ {
@ -247,13 +303,12 @@ public class MainActivity extends ActionBarActivity
/** /**
* Move selected files to a new album. The album is located at appDirectoryPath/albumName * Move selected files to a new album. The album is located at appDirectoryPath/albumName
* @param albumName * @param albumName name of the Album to move the files to
*/ */
private void moveFiles(String albumName) private void moveFiles(String albumName)
{ {
for(Uri u: sharedMedia) for(String srcDest : sharedMedia)
{ {
String srcDest = getRealPathFromURI(this, u);
if(!moveImageFromTo(srcDest, calcTargetPath(albumName, srcDest))) if(!moveImageFromTo(srcDest, calcTargetPath(albumName, srcDest)))
{ {
System.out.println("Fail: " +srcDest); System.out.println("Fail: " +srcDest);
@ -263,9 +318,9 @@ public class MainActivity extends ActionBarActivity
/** /**
* Move file src to target. * Move file src to target.
* @param src * @param src url of the file that will be moved
* @param target * @param target url of the destination
* @return * @return success
*/ */
private boolean moveImageFromTo(String src, String target) private boolean moveImageFromTo(String src, String target)
{ {
@ -316,6 +371,10 @@ public class MainActivity extends ActionBarActivity
} }
} }
/**
* Add the file on path to the MediaStore
* @param path url of the file
*/
private void addFileToMediaStore(String path) private void addFileToMediaStore(String path)
{ {
MediaScannerConnection.scanFile( MediaScannerConnection.scanFile(
@ -332,6 +391,12 @@ public class MainActivity extends ActionBarActivity
}); });
} }
/**
* calculate the new filepath for a file according to the album name
* @param albumName name of the Album
* @param srcDest url of the file
* @return full url of the destination
*/
private String calcTargetPath(String albumName, String srcDest) private String calcTargetPath(String albumName, String srcDest)
{ {
String file = getAppDirectoryPath()+albumName+srcDest.substring(srcDest.lastIndexOf("/")); String file = getAppDirectoryPath()+albumName+srcDest.substring(srcDest.lastIndexOf("/"));
@ -339,6 +404,10 @@ public class MainActivity extends ActionBarActivity
return file; return file;
} }
/**
* Set the apps directory path to <externalMemory>/Pictures/Albums
* @return new path
*/
public String resetAppDirectoryPath() public String resetAppDirectoryPath()
{ {
String path = Environment.getExternalStorageDirectory().getAbsolutePath()+"/Pictures/Albums/"; String path = Environment.getExternalStorageDirectory().getAbsolutePath()+"/Pictures/Albums/";
@ -349,6 +418,10 @@ public class MainActivity extends ActionBarActivity
return path; return path;
} }
/**
* return the current app directory path
* @return path where to store new albums
*/
public String getAppDirectoryPath() public String getAppDirectoryPath()
{ {
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
@ -360,6 +433,11 @@ public class MainActivity extends ActionBarActivity
} }
} }
/**
* Return a list of Strings that represent the names of the folders on dirPath
* @param dirPath path of the directory
* @return list of subfolders of the directory
*/
public ArrayList<String> getFoldersOnDirectory(String dirPath) public ArrayList<String> getFoldersOnDirectory(String dirPath)
{ {
File parent = new File(dirPath); File parent = new File(dirPath);
@ -375,10 +453,17 @@ public class MainActivity extends ActionBarActivity
return subDirs; return subDirs;
} }
/**
* Get a real path from a uri.
* @param context context
* @param contentUri uri
* @return real path
*/
public String getRealPathFromURI(Context context, Uri contentUri) public String getRealPathFromURI(Context context, Uri contentUri)
{ {
String[] projection = {MediaStore.Images.Media.DATA}; String[] projection = {MediaStore.Images.Media.DATA};
Cursor cursor = context.getContentResolver().query(contentUri, projection, null, null, null); Cursor cursor = context.getContentResolver().query(contentUri, projection, null, null, null);
if(cursor == null) return null;
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst(); cursor.moveToFirst();
String realPath = cursor.getString(column_index); String realPath = cursor.getString(column_index);
@ -387,6 +472,11 @@ public class MainActivity extends ActionBarActivity
return realPath; return realPath;
} }
/**
* Return the mimeType of the file on url
* @param url url
* @return mimeType (eg. "image/jpg")
*/
public static String getMimeType(String url) public static String getMimeType(String url)
{ {
String type = null; String type = null;
@ -406,19 +496,26 @@ public class MainActivity extends ActionBarActivity
@Override @Override
protected Void doInBackground(String... params) protected Void doInBackground(String... params)
{ {
InputStream in = null; InputStream in;
OutputStream out = null; OutputStream out;
String src = params[0]; String src = params[0];
String target = params[1]; String target = params[1];
try try
{ {
File dir = new File(src.substring(0, src.lastIndexOf("/"))); File dir = new File(src.substring(0, src.lastIndexOf("/")));
if (!dir.exists()) if (!dir.exists())
dir.mkdirs(); {
handleUnsupportedMedia();
return null;
}
in = new FileInputStream(src); in = new FileInputStream(src);
File outFile = new File(target.substring(0, target.lastIndexOf("/"))); File outFile = new File(target.substring(0, target.lastIndexOf("/")));
if (!outFile.exists()) if (!outFile.exists())
outFile.mkdirs(); if(!outFile.mkdirs())
{
handleCouldNotWrite(outFile.getAbsolutePath());
return null;
}
out = new FileOutputStream(target); out = new FileOutputStream(target);
byte[] buffer = new byte[1024]; byte[] buffer = new byte[1024];

View file

@ -7,12 +7,14 @@ import android.preference.PreferenceActivity;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
/** /**
* Created by vanitas on 10.05.15. * SettingsActivity for handling Preferences
* @author vanitas
*/ */
public class SettingsActivity extends PreferenceActivity implements SharedPreferences.OnSharedPreferenceChangeListener public class SettingsActivity extends PreferenceActivity implements SharedPreferences.OnSharedPreferenceChangeListener
{ {
public final static String KEY_PREF_APP_PATH = "pref_app_path"; public final static String KEY_PREF_APP_PATH = "pref_app_path";
@SuppressWarnings("all")
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);

View file

@ -8,6 +8,10 @@
<string name="dialog_content_unimplemented_feature">Diese Funktion ist noch nicht fertig implementiert.\nSchau mal nach Updates :)</string> <string name="dialog_content_unimplemented_feature">Diese Funktion ist noch nicht fertig implementiert.\nSchau mal nach Updates :)</string>
<string name="dialog_title_first_run">Achtung!</string> <string name="dialog_title_first_run">Achtung!</string>
<string name="dialog_content_first_run">Diese App ist in einer frühen Entwicklungsphase und könnte instabil sein! Sei vorsichtig, wenn du deine schönsten Bilder verwaltest. Die App könnte abstürzen und die geteilten Daten vernichten!</string> <string name="dialog_content_first_run">Diese App ist in einer frühen Entwicklungsphase und könnte instabil sein! Sei vorsichtig, wenn du deine schönsten Bilder verwaltest. Die App könnte abstürzen und die geteilten Daten vernichten!</string>
<string name="dialog_title_unsupported_media">Nicht unterstützte Operation</string>
<string name="dialog_content_unsupported_media">Die geteilten Dateien werden nicht unterstützt.\nVerschiebe Fotos und Videos in neue Alben, indem du sie aus der Android Galerie App teilst.</string>
<string name="dialog_title_write_failed">Fehler!</string>
<string name="dialog_content_write_failed">Konnte folgende Dateien nicht schreiben. Vielleicht fehlen Berechtigungen?</string>
<string name="toast_invalid_album_name">Bitte gebe einen Albumnamen ein!</string> <string name="toast_invalid_album_name">Bitte gebe einen Albumnamen ein!</string>
<string name="action_settings">Einstellungen</string> <string name="action_settings">Einstellungen</string>
<string name="ok">OK</string> <string name="ok">OK</string>
@ -17,4 +21,5 @@
<string name="pref_title_app_path">Speicherort</string> <string name="pref_title_app_path">Speicherort</string>
<string name="pref_description_app_path">Wo sollen neue Alben angelegt werden? Um den Speicherort auf den Standardwert zurückzusetzen, lösche diesen Wert und starte die App neu.</string> <string name="pref_description_app_path">Wo sollen neue Alben angelegt werden? Um den Speicherort auf den Standardwert zurückzusetzen, lösche diesen Wert und starte die App neu.</string>
<string name="title_activity_settings">Einstellungen</string>
</resources> </resources>

View file

@ -8,6 +8,10 @@
<string name="dialog_content_unimplemented_feature">This feature is not implemented yet.\nCheck out updates :)</string> <string name="dialog_content_unimplemented_feature">This feature is not implemented yet.\nCheck out updates :)</string>
<string name="dialog_title_first_run">Warning!</string> <string name="dialog_title_first_run">Warning!</string>
<string name="dialog_content_first_run">This app is an early alpha version and can be unstable! Do not rely on it while handling your most precious images. The app may crash and destroy your data!</string> <string name="dialog_content_first_run">This app is an early alpha version and can be unstable! Do not rely on it while handling your most precious images. The app may crash and destroy your data!</string>
<string name="dialog_title_unsupported_media">Unsupported Media</string>
<string name="dialog_content_unsupported_media">The shared files are not supported.\nStick photos into albums by sharing them from Androids Gallery App.</string>
<string name="dialog_title_write_failed">Error!</string>
<string name="dialog_content_write_failed">Could not write the following files. Maybe missing Permissions?</string>
<string name="toast_invalid_album_name">Please enter valid album name!</string> <string name="toast_invalid_album_name">Please enter valid album name!</string>
<string name="action_settings">Settings</string> <string name="action_settings">Settings</string>
<string name="ok">OK</string> <string name="ok">OK</string>
@ -17,4 +21,5 @@
<string name="pref_title_app_path">Album Directory</string> <string name="pref_title_app_path">Album Directory</string>
<string name="pref_description_app_path">In which directory are Albums located? Delete value and restart the app to reset this to default.</string> <string name="pref_description_app_path">In which directory are Albums located? Delete value and restart the app to reset this to default.</string>
<string name="title_activity_settings">Settings</string>
</resources> </resources>

View file

@ -1,61 +0,0 @@
<resources>
<string name="title_activity_settings">Settings</string>
<!-- Strings related to Settings -->
<!-- Example General settings -->
<string name="pref_header_general">General</string>
<string name="pref_title_social_recommendations">Enable social recommendations</string>
<string name="pref_description_social_recommendations">Recommendations for people to contact
based on your message history
</string>
<string name="pref_title_display_name">Display name</string>
<string name="pref_default_display_name">John Smith</string>
<string name="pref_title_add_friends_to_messages">Add friends to messages</string>
<string-array name="pref_example_list_titles">
<item>Always</item>
<item>When possible</item>
<item>Never</item>
</string-array>
<string-array name="pref_example_list_values">
<item>1</item>
<item>0</item>
<item>-1</item>
</string-array>
<!-- Example settings for Data & Sync -->
<string name="pref_header_data_sync">Data &amp; sync</string>
<string name="pref_title_sync_frequency">Sync frequency</string>
<string-array name="pref_sync_frequency_titles">
<item>15 minutes</item>
<item>30 minutes</item>
<item>1 hour</item>
<item>3 hours</item>
<item>6 hours</item>
<item>Never</item>
</string-array>
<string-array name="pref_sync_frequency_values">
<item>15</item>
<item>30</item>
<item>60</item>
<item>180</item>
<item>360</item>
<item>-1</item>
</string-array>
<string name="pref_title_system_sync_settings">System sync settings</string>
<!-- Example settings for Notifications -->
<string name="pref_header_notifications">Notifications</string>
<string name="pref_title_new_message_notifications">New message notifications</string>
<string name="pref_title_ringtone">Ringtone</string>
<string name="pref_ringtone_silent">Silent</string>
<string name="pref_title_vibrate">Vibrate</string>
</resources>