use of com.codename1.rad.nodes.ActionNode.Category in project CodenameOne by codenameone.
the class AndroidImplementation method installNotificationActionCategories.
/**
* Action categories are defined on the Main class by implementing the PushActionsProvider, however
* the main class may not be available to the push receiver, so we need to save these categories
* to the file system when the app is installed, then the push receiver can load these actions
* when it sends a push while the app isn't running.
* @param provider A reference to the App's main class
* @throws IOException
*/
public static void installNotificationActionCategories(PushActionsProvider provider) throws IOException {
// Assume that CN1 is running... this will run when the app starts
// up
Context context = getContext();
boolean requiresUpdate = false;
File categoriesFile = new File(activity.getFilesDir().getAbsolutePath() + "/" + FILE_NAME_NOTIFICATION_CATEGORIES);
if (!categoriesFile.exists()) {
requiresUpdate = true;
}
if (!requiresUpdate) {
try {
PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getApplicationContext().getPackageName(), PackageManager.GET_PERMISSIONS);
if (packageInfo.lastUpdateTime > categoriesFile.lastModified()) {
requiresUpdate = true;
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
if (!requiresUpdate) {
return;
}
OutputStream os = getContext().openFileOutput(FILE_NAME_NOTIFICATION_CATEGORIES, 0);
PushActionCategory[] categories = provider.getPushActionCategories();
javax.xml.parsers.DocumentBuilderFactory docFactory = javax.xml.parsers.DocumentBuilderFactory.newInstance();
javax.xml.parsers.DocumentBuilder docBuilder;
try {
docBuilder = docFactory.newDocumentBuilder();
} catch (ParserConfigurationException ex) {
Logger.getLogger(AndroidImplementation.class.getName()).log(Level.SEVERE, null, ex);
throw new IOException("Faield to create document builder for creating notification categories XML document", ex);
}
// root elements
org.w3c.dom.Document doc = docBuilder.newDocument();
org.w3c.dom.Element root = (org.w3c.dom.Element) doc.createElement("categories");
doc.appendChild(root);
for (PushActionCategory category : categories) {
org.w3c.dom.Element categoryEl = (org.w3c.dom.Element) doc.createElement("category");
org.w3c.dom.Attr idAttr = doc.createAttribute("id");
idAttr.setValue(category.getId());
categoryEl.setAttributeNode(idAttr);
for (PushAction action : category.getActions()) {
org.w3c.dom.Element actionEl = (org.w3c.dom.Element) doc.createElement("action");
org.w3c.dom.Attr actionIdAttr = doc.createAttribute("id");
actionIdAttr.setValue(action.getId());
actionEl.setAttributeNode(actionIdAttr);
org.w3c.dom.Attr actionTitleAttr = doc.createAttribute("title");
if (action.getTitle() != null) {
actionTitleAttr.setValue(action.getTitle());
} else {
actionTitleAttr.setValue(action.getId());
}
actionEl.setAttributeNode(actionTitleAttr);
if (action.getIcon() != null) {
org.w3c.dom.Attr actionIconAttr = doc.createAttribute("icon");
String iconVal = action.getIcon();
try {
// We'll store the resource IDs for the icon
// rather than the icon name because that is what
// the push notifications require.
iconVal = "" + context.getResources().getIdentifier(iconVal, "drawable", context.getPackageName());
actionIconAttr.setValue(iconVal);
actionEl.setAttributeNode(actionIconAttr);
} catch (Exception ex) {
ex.printStackTrace();
}
}
if (action.getTextInputPlaceholder() != null) {
org.w3c.dom.Attr textInputPlaceholderAttr = doc.createAttribute("textInputPlaceholder");
textInputPlaceholderAttr.setValue(action.getTextInputPlaceholder());
actionEl.setAttributeNode(textInputPlaceholderAttr);
}
if (action.getTextInputButtonText() != null) {
org.w3c.dom.Attr textInputButtonTextAttr = doc.createAttribute("textInputButtonText");
textInputButtonTextAttr.setValue(action.getTextInputButtonText());
actionEl.setAttributeNode(textInputButtonTextAttr);
}
categoryEl.appendChild(actionEl);
}
root.appendChild(categoryEl);
}
try {
javax.xml.transform.TransformerFactory transformerFactory = javax.xml.transform.TransformerFactory.newInstance();
javax.xml.transform.Transformer transformer = transformerFactory.newTransformer();
javax.xml.transform.dom.DOMSource source = new javax.xml.transform.dom.DOMSource(doc);
javax.xml.transform.stream.StreamResult result = new javax.xml.transform.stream.StreamResult(os);
transformer.transform(source, result);
} catch (Exception ex) {
throw new IOException("Failed to save notification categories as XML.", ex);
}
}
use of com.codename1.rad.nodes.ActionNode.Category in project CodenameOne by codenameone.
the class AndroidImplementation method addActionsToNotification.
/**
* Adds actions to a push notification. This is called by the Push broadcast receiver probably before
* Codename One is initialized
* @param provider Reference to the app's main class which implements PushActionsProvider
* @param categoryId The category ID of the push notification.
* @param builder The builder for the push notification.
* @param targetIntent The target intent... this should go to the app's main Activity.
* @param context The current context (inside the Broadcast receiver).
* @throws IOException
*/
public static void addActionsToNotification(PushActionsProvider provider, String categoryId, NotificationCompat.Builder builder, Intent targetIntent, Context context) throws IOException {
// NOTE: THis will likely run when the main activity isn't running so we won't have
// access to any display properties... just native Android APIs will be accessible.
PushActionCategory category = null;
PushActionCategory[] categories;
if (provider != null) {
categories = provider.getPushActionCategories();
} else {
categories = getInstalledPushActionCategories(context);
}
for (PushActionCategory candidateCategory : categories) {
if (categoryId.equals(candidateCategory.getId())) {
category = candidateCategory;
break;
}
}
if (category == null) {
return;
}
int requestCode = 1;
for (PushAction action : category.getActions()) {
Intent newIntent = (Intent) targetIntent.clone();
newIntent.putExtra("pushActionId", action.getId());
PendingIntent contentIntent = createPendingIntent(context, requestCode++, newIntent);
try {
int iconId = 0;
try {
iconId = Integer.parseInt(action.getIcon());
} catch (Exception ex) {
}
// android.app.Notification.Action.Builder actionBuilder = new android.app.Notification.Action.Builder(iconId, action.getTitle(), contentIntent);
System.out.println("Adding action " + action.getId() + ", " + action.getTitle() + ", icon=" + iconId);
if (ActionWrapper.BuilderWrapper.isSupported()) {
// We need to take this abstracted "wrapper" approach because the Action.Builder class, and RemoteInput class
// aren't available until API 22.
// These classes use reflection to provide support for these classes safely.
ActionWrapper.BuilderWrapper actionBuilder = new ActionWrapper.BuilderWrapper(iconId, action.getTitle(), contentIntent);
if (action.getTextInputPlaceholder() != null && RemoteInputWrapper.isSupported()) {
RemoteInputWrapper.BuilderWrapper remoteInputBuilder = new RemoteInputWrapper.BuilderWrapper(action.getId() + "$Result");
remoteInputBuilder.setLabel(action.getTextInputPlaceholder());
RemoteInputWrapper remoteInput = remoteInputBuilder.build();
actionBuilder.addRemoteInput(remoteInput);
}
ActionWrapper actionWrapper = actionBuilder.build();
new NotificationCompatWrapper.BuilderWrapper(builder).addAction(actionWrapper);
} else {
builder.addAction(iconId, action.getTitle(), contentIntent);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
use of com.codename1.rad.nodes.ActionNode.Category in project CodenameOne by codenameone.
the class DoughnutChart method draw.
/**
* The graphical representation of the doughnut chart.
*
* @param canvas the canvas to paint to
* @param x the top left x value of the view to draw to
* @param y the top left y value of the view to draw to
* @param width the width of the view to draw to
* @param height the height of the view to draw to
* @param paint the paint
*/
@Override
public void draw(Canvas canvas, int x, int y, int width, int height, Paint paint) {
paint.setAntiAlias(mRenderer.isAntialiasing());
paint.setStyle(Style.FILL);
paint.setTextSize(mRenderer.getLabelsTextSize());
int legendSize = getLegendSize(mRenderer, height / 5, 0);
int left = x;
int top = y;
int right = x + width;
int cLength = mDataset.getCategoriesCount();
String[] categories = new String[cLength];
for (int category = 0; category < cLength; category++) {
categories[category] = mDataset.getCategory(category);
}
if (mRenderer.isFitLegend()) {
legendSize = drawLegend(canvas, mRenderer, categories, left, right, y, width, height, legendSize, paint, true);
}
int bottom = y + height - legendSize;
drawBackground(mRenderer, canvas, x, y, width, height, paint, false, DefaultRenderer.NO_COLOR);
mStep = SHAPE_WIDTH * 3 / 4;
int mRadius = Math.min(Math.abs(right - left), Math.abs(bottom - top));
double rCoef = 0.35 * mRenderer.getScale();
double decCoef = 0.2 / cLength;
int radius = (int) (mRadius * rCoef);
if (autoCalculateCenter || mCenterX == NO_VALUE) {
mCenterX = (left + right) / 2;
}
if (autoCalculateCenter || mCenterY == NO_VALUE) {
mCenterY = (bottom + top) / 2;
}
float shortRadius = radius * 0.9f;
float longRadius = radius * 1.1f;
List<Rectangle2D> prevLabelsBounds = new ArrayList<Rectangle2D>();
for (int category = 0; category < cLength; category++) {
int sLength = mDataset.getItemCount(category);
double total = 0;
String[] titles = new String[sLength];
for (int i = 0; i < sLength; i++) {
total += mDataset.getValues(category)[i];
titles[i] = mDataset.getTitles(category)[i];
}
float currentAngle = mRenderer.getStartAngle();
Rectangle2D oval = PkgUtils.makeRect(mCenterX - radius, mCenterY - radius, mCenterX + radius, mCenterY + radius);
for (int i = 0; i < sLength; i++) {
paint.setColor(mRenderer.getSeriesRendererAt(i).getColor());
float value = (float) mDataset.getValues(category)[i];
float angle = (float) (value / total * 360);
canvas.drawArc(oval, currentAngle, angle, true, paint);
drawLabel(canvas, mDataset.getTitles(category)[i], mRenderer, prevLabelsBounds, mCenterX, mCenterY, shortRadius, longRadius, currentAngle, angle, left, right, mRenderer.getLabelsColor(), paint, true, false);
currentAngle += angle;
}
radius -= (int) mRadius * decCoef;
shortRadius -= mRadius * decCoef - 2;
if (mRenderer.getBackgroundColor() != 0) {
paint.setColor(mRenderer.getBackgroundColor());
} else {
paint.setColor(ColorUtil.WHITE);
}
paint.setStyle(Style.FILL);
oval = PkgUtils.makeRect(mCenterX - radius, mCenterY - radius, mCenterX + radius, mCenterY + radius);
canvas.drawArc(oval, 0, 360, true, paint);
radius -= 1;
}
prevLabelsBounds.clear();
drawLegend(canvas, mRenderer, categories, left, right, y, width, height, legendSize, paint, false);
drawTitle(canvas, x, y, width, paint);
}
use of com.codename1.rad.nodes.ActionNode.Category in project CodenameOne by codenameone.
the class WebPushTest method push.
@Override
public void push(String value) {
PushContent data = PushContent.get();
if (data != null) {
System.out.println("Image URL: " + data.getImageUrl());
System.out.println("Category: " + data.getCategory());
System.out.println("Action: " + data.getActionId());
System.out.println("Text Response: " + data.getTextResponse());
} else {
System.out.println("PushContent is null");
}
System.out.println("Push " + value);
Display.getInstance().callSerially(() -> {
Dialog.show("Push received", value, "OK", null);
});
}
use of com.codename1.rad.nodes.ActionNode.Category in project CodenameOne by codenameone.
the class AndroidImplementation method getInstalledPushActionCategories.
/**
* Retrieves the app's available push action categories from the XML file in which they
* should have been installed on the first load.
* @param context
* @return
* @throws IOException
*/
private static PushActionCategory[] getInstalledPushActionCategories(Context context) throws IOException {
// NOTE: This method may be called from the PushReceiver when the app isn't running so we can't access
// the main activity context, display properties, or any CN1 stuff. Just native android
File categoriesFile = new File(context.getFilesDir().getAbsolutePath() + "/" + FILE_NAME_NOTIFICATION_CATEGORIES);
if (!categoriesFile.exists()) {
return new PushActionCategory[0];
}
javax.xml.parsers.DocumentBuilderFactory docFactory = javax.xml.parsers.DocumentBuilderFactory.newInstance();
javax.xml.parsers.DocumentBuilder docBuilder;
try {
docBuilder = docFactory.newDocumentBuilder();
} catch (ParserConfigurationException ex) {
Logger.getLogger(AndroidImplementation.class.getName()).log(Level.SEVERE, null, ex);
throw new IOException("Faield to create document builder for creating notification categories XML document", ex);
}
org.w3c.dom.Document doc;
try {
doc = docBuilder.parse(context.openFileInput(FILE_NAME_NOTIFICATION_CATEGORIES));
} catch (SAXException ex) {
Logger.getLogger(AndroidImplementation.class.getName()).log(Level.SEVERE, null, ex);
throw new IOException("Failed to parse instaled push action categories", ex);
}
org.w3c.dom.Element root = doc.getDocumentElement();
java.util.List<PushActionCategory> out = new ArrayList<PushActionCategory>();
org.w3c.dom.NodeList l = root.getElementsByTagName("category");
int len = l.getLength();
for (int i = 0; i < len; i++) {
org.w3c.dom.Element el = (org.w3c.dom.Element) l.item(i);
java.util.List<PushAction> actions = new ArrayList<PushAction>();
org.w3c.dom.NodeList al = el.getElementsByTagName("action");
int alen = al.getLength();
for (int j = 0; j < alen; j++) {
org.w3c.dom.Element actionEl = (org.w3c.dom.Element) al.item(j);
String textInputPlaceholder = actionEl.hasAttribute("textInputPlaceholder") ? actionEl.getAttribute("textInputPlaceholder") : null;
String textInputButtonText = actionEl.hasAttribute("textInputButtonText") ? actionEl.getAttribute("textInputButtonText") : null;
PushAction action = new PushAction(actionEl.getAttribute("id"), actionEl.getAttribute("title"), actionEl.getAttribute("icon"), textInputPlaceholder, textInputButtonText);
actions.add(action);
}
PushActionCategory cat = new PushActionCategory((String) el.getAttribute("id"), actions.toArray(new PushAction[actions.size()]));
out.add(cat);
}
return out.toArray(new PushActionCategory[out.size()]);
}
Aggregations