Commit 4f4147d0 by Sebastián Katzer

Fixes #588 crash when basename & extension can't be extracted

parent 52054f5d
......@@ -5,6 +5,7 @@ Please also read the [Upgrade Guide](https://github.com/katzer/cordova-plugin-lo
#### Version 0.8.3 (not yet released)
- New "quarter" intervall for iOS & Android
- Fixed #588 crash when basename & extension can't be extracted (Android)
- Fixed #732 loop between update and trigger (Android)
- Fixed #710 crash due to >500 notifications (Android)
- Fixed #682 crash while resuming app from notification (Android 6)
......
......@@ -42,6 +42,7 @@ import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.UUID;
/**
* Util class to map unified asset URIs to native URIs. URIs like file:///
......@@ -61,15 +62,15 @@ class AssetUtil {
// resources and app directory.
private final Context context;
/**
* Constructor
*
* @param context
/**
* Constructor
*
* @param context
* Application context
*/
private AssetUtil(Context context) {
this.context = context;
}
*/
private AssetUtil(Context context) {
this.context = context;
}
/**
* Static method to retrieve class instance.
......@@ -100,223 +101,199 @@ class AssetUtil {
return parse(path);
}
/**
* The URI for a path.
*
* @param path
/**
* The URI for a path.
*
* @param path
* The given path
*/
*/
Uri parse (String path) {
if (path.startsWith("res:")) {
return getUriForResourcePath(path);
} else if (path.startsWith("file:///")) {
return getUriFromPath(path);
} else if (path.startsWith("file://")) {
return getUriFromAsset(path);
} else if (path.startsWith("http")){
return getUriFromRemote(path);
}
return Uri.EMPTY;
}
/**
* URI for a file.
*
* @param path
* Absolute path like file:///...
*
* @return
* URI pointing to the given path
*/
private Uri getUriFromPath(String path) {
String absPath = path.replaceFirst("file://", "");
File file = new File(absPath);
if (!file.exists()) {
Log.e("Asset", "File not found: " + file.getAbsolutePath());
return Uri.EMPTY;
}
return Uri.fromFile(file);
}
/**
* URI for an asset.
*
* @param path
* Asset path like file://...
*
* @return
if (path.startsWith("res:")) {
return getUriForResourcePath(path);
} else if (path.startsWith("file:///")) {
return getUriFromPath(path);
} else if (path.startsWith("file://")) {
return getUriFromAsset(path);
} else if (path.startsWith("http")){
return getUriFromRemote(path);
}
return Uri.EMPTY;
}
/**
* URI for a file.
*
* @param path
* Absolute path like file:///...
*
* @return
* URI pointing to the given path
*/
private Uri getUriFromAsset(String path) {
File dir = context.getExternalCacheDir();
*/
private Uri getUriFromPath(String path) {
String absPath = path.replaceFirst("file://", "");
File file = new File(absPath);
if (!file.exists()) {
Log.e("Asset", "File not found: " + file.getAbsolutePath());
return Uri.EMPTY;
}
if (dir == null) {
Log.e("Asset", "Missing external cache dir");
return Uri.EMPTY;
}
return Uri.fromFile(file);
}
/**
* URI for an asset.
*
* @param path
* Asset path like file://...
*
* @return
* URI pointing to the given path
*/
private Uri getUriFromAsset(String path) {
String resPath = path.replaceFirst("file:/", "www");
String fileName = resPath.substring(resPath.lastIndexOf('/') + 1);
String storage = dir.toString() + STORAGE_FOLDER;
File file = new File(storage, fileName);
File file = getTmpFile(fileName);
//noinspection ResultOfMethodCallIgnored
new File(storage).mkdir();
if (file == null) {
Log.e("Asset", "Missing external cache dir");
return Uri.EMPTY;
}
try {
AssetManager assets = context.getAssets();
FileOutputStream outStream = new FileOutputStream(file);
InputStream inputStream = assets.open(resPath);
try {
AssetManager assets = context.getAssets();
FileOutputStream outStream = new FileOutputStream(file);
InputStream inputStream = assets.open(resPath);
copyFile(inputStream, outStream);
copyFile(inputStream, outStream);
outStream.flush();
outStream.close();
outStream.flush();
outStream.close();
return Uri.fromFile(file);
return Uri.fromFile(file);
} catch (Exception e) {
Log.e("Asset", "File not found: assets/" + resPath);
e.printStackTrace();
}
} catch (Exception e) {
Log.e("Asset", "File not found: assets/" + resPath);
e.printStackTrace();
}
return Uri.EMPTY;
}
return Uri.EMPTY;
}
/**
* The URI for a resource.
*
* @param path
* The given relative path
*
* @return
/**
* The URI for a resource.
*
* @param path
* The given relative path
*
* @return
* URI pointing to the given path
*/
private Uri getUriForResourcePath(String path) {
File dir = context.getExternalCacheDir();
if (dir == null) {
Log.e("Asset", "Missing external cache dir");
return Uri.EMPTY;
}
*/
private Uri getUriForResourcePath(String path) {
String resPath = path.replaceFirst("res://", "");
int resId = getResIdForDrawable(resPath);
File file = getTmpFile();
int resId = getResIdForDrawable(resPath);
if (resId == 0) {
Log.e("Asset", "File not found: " + resPath);
return Uri.EMPTY;
}
String resName = extractResourceName(resPath);
String extName = extractResourceExtension(resPath);
String storage = dir.toString() + STORAGE_FOLDER;
File file = new File(storage, resName + extName);
if (resId == 0) {
Log.e("Asset", "File not found: " + resPath);
return Uri.EMPTY;
}
//noinspection ResultOfMethodCallIgnored
new File(storage).mkdir();
if (file == null) {
Log.e("Asset", "Missing external cache dir");
return Uri.EMPTY;
}
try {
Resources res = context.getResources();
FileOutputStream outStream = new FileOutputStream(file);
InputStream inputStream = res.openRawResource(resId);
copyFile(inputStream, outStream);
try {
Resources res = context.getResources();
FileOutputStream outStream = new FileOutputStream(file);
InputStream inputStream = res.openRawResource(resId);
copyFile(inputStream, outStream);
outStream.flush();
outStream.close();
outStream.flush();
outStream.close();
return Uri.fromFile(file);
return Uri.fromFile(file);
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
return Uri.EMPTY;
}
}
/**
* Uri from remote located content.
/**
* Uri from remote located content.
*
* @param path
* @param path
* Remote address
*
* @return
* @return
* Uri of the downloaded file
*/
private Uri getUriFromRemote(String path) {
File dir = context.getExternalCacheDir();
*/
private Uri getUriFromRemote(String path) {
File file = getTmpFile();
if (dir == null) {
if (file == null) {
Log.e("Asset", "Missing external cache dir");
return Uri.EMPTY;
}
String resName = extractResourceName(path);
String extName = extractResourceExtension(path);
String storage = dir.toString() + STORAGE_FOLDER;
File file = new File(storage, resName + extName);
//noinspection ResultOfMethodCallIgnored
new File(storage).mkdir();
try {
URL url = new URL(path);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
StrictMode.ThreadPolicy policy =
new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.ThreadPolicy policy =
new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
StrictMode.setThreadPolicy(policy);
connection.setRequestProperty("Connection", "close");
connection.setConnectTimeout(5000);
connection.connect();
connection.connect();
InputStream input = connection.getInputStream();
FileOutputStream outStream = new FileOutputStream(file);
InputStream input = connection.getInputStream();
FileOutputStream outStream = new FileOutputStream(file);
copyFile(input, outStream);
copyFile(input, outStream);
outStream.flush();
outStream.close();
outStream.flush();
outStream.close();
return Uri.fromFile(file);
return Uri.fromFile(file);
} catch (MalformedURLException e) {
Log.e("Asset", "Incorrect URL");
e.printStackTrace();
} catch (FileNotFoundException e) {
Log.e("Asset", "Failed to create new File from HTTP Content");
e.printStackTrace();
} catch (IOException e) {
Log.e("Asset", "No Input can be created from http Stream");
e.printStackTrace();
}
} catch (MalformedURLException e) {
Log.e("Asset", "Incorrect URL");
e.printStackTrace();
} catch (FileNotFoundException e) {
Log.e("Asset", "Failed to create new File from HTTP Content");
e.printStackTrace();
} catch (IOException e) {
Log.e("Asset", "No Input can be created from http Stream");
e.printStackTrace();
}
return Uri.EMPTY;
}
/**
* Copy content from input stream into output stream.
*
* @param in
* The input stream
* @param out
* The output stream
*/
private void copyFile(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
}
}
/**
* Copy content from input stream into output stream.
*
* @param in
* The input stream
* @param out
* The output stream
*/
private void copyFile(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
}
/**
* Resource ID for drawable.
......@@ -343,7 +320,7 @@ class AssetUtil {
* Resource path as string
*/
int getResIdForDrawable(String clsName, String resPath) {
String drawable = extractResourceName(resPath);
String drawable = getBaseName(resPath);
int resId = 0;
try {
......@@ -396,7 +373,7 @@ class AssetUtil {
* @param resPath
* Resource path as string
*/
private String extractResourceName (String resPath) {
private String getBaseName (String resPath) {
String drawable = resPath;
if (drawable.contains("/")) {
......@@ -411,19 +388,39 @@ class AssetUtil {
}
/**
* Extract extension of drawable resource from path.
* Returns a file located under the external cache dir of that app.
*
* @param resPath
* Resource path as string
* @return
* File with a random UUID name
*/
private String extractResourceExtension (String resPath) {
String extName = "png";
private File getTmpFile () {
// If random UUID is not be enough see
// https://github.com/LukePulverenti/cordova-plugin-local-notifications/blob/267170db14044cbeff6f4c3c62d9b766b7a1dd62/src/android/notification/AssetUtil.java#L255
return getTmpFile(UUID.randomUUID().toString());
}
if (resPath.contains(".")) {
extName = resPath.substring(resPath.lastIndexOf('.'));
/**
* Returns a file located under the external cache dir of that app.
*
* @param name
* The name of the file
* @return
* File with the provided name
*/
private File getTmpFile (String name) {
File dir = context.getExternalCacheDir();
if (dir == null) {
Log.e("Asset", "Missing external cache dir");
return null;
}
return extName;
String storage = dir.toString() + STORAGE_FOLDER;
//noinspection ResultOfMethodCallIgnored
new File(storage).mkdir();
return new File(storage, name);
}
/**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment