Android: MobileFirst sending data from Native to cross page - android

My Task is as follows: using IBM MobileFirst create a Hybrid app and implement a JS calculator. show date retrieved from native java APIs to the web page.
My attempts:
I followed Documentations here and implemented the whole Native code onCreate method
I found this answer"the first one" illustrating that i should use it on onInitWebFrameworkComplete,
Solution provided didn't work
I am working with MobileFirst version 7
full sample code is provided
Suggestion: should i create the whole action bar in native code then merge it in the cross ui, is that available? I only need to send a petite string of date

I am not clear on your attempts, so here is a quick demonstration how to click a button in HTML and trigger the Send Action API to get the current Date in Java and return it to JavaScript, and then display it.
index.html
<button onclick="getDateFromJava();">show current date from Java</button>
main.js
function wlCommonInit(){
WL.App.addActionReceiver ("returneDdateFromJava", returnedDateFromJava);
}
function getDateFromJava() {
WL.App.sendActionToNative("retrieveDate");
}
function returnedDateFromJava(received){
if (received.action === "returnedDateFromJava"){
alert (JSON.stringify(received));
}
}
main Java class file
Find onInitWebFrameworkComplete
Add an ActionReceiver after the else:
import com.worklight.androidgap.api.WLActionReceiver;
...
...
public void onInitWebFrameworkComplete(WLInitWebFrameworkResult result){
if (result.getStatusCode() == WLInitWebFrameworkResult.SUCCESS) {
super.loadUrl(WL.getInstance().getMainHtmlFilePath());
} else {
handleWebFrameworkInitFailure(result);
}
ActionReceiver ActionReceiver = new ActionReceiver();
WL.getInstance().addActionReceiver(ActionReceiver);
}
ActionReceiver class
package com.getDateApp;
import java.util.Date;
import org.json.JSONException;
import org.json.JSONObject;
import com.worklight.androidgap.api.WL;
import com.worklight.androidgap.api.WLActionReceiver;
public class ActionReceiver implements WLActionReceiver{
public void onActionReceived(String action, JSONObject data){
if (action.equals("retrieveDate")){
Date date = new Date();
JSONObject returnedDate = new JSONObject();
try {
returnedDate.put("dateFromJava", date);
} catch (JSONException e) {
e.printStackTrace();
}
WL.getInstance().sendActionToJS("returnedDateFromJava", returnedDate);
}
}
}

Related

Implement Play Asset Delivery In flutter

How to implement on-demand Play Asset Delivery in flutter through methodchannels.
Actually i am trying to make a dashboard for some app which accesses assets using ContentProvider so i thought play asset delivery might work here.
I know that same can be achieved using deferred components and I have already tried deferred components which is provided by flutter.
You can find it here
Currently, there is an issue with flutter which causes assets to not load when deferred. You can find a link to the issue here.
I do not have any idea of native language and this is the only option I have right now which is implementing a methodchannel so any help would be appreciated
I dont think you can achieve the same thing using play asset delivery. You can try a workaround for this
Disable android:enabled by default by adding android:enabled="false" in your content provider and then use below methodchannel to enable it later
package dev.blah.blah;
import androidx.annotation.NonNull;
import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.plugin.common.MethodChannel;
import android.content.ContextWrapper;
import android.widget.Toast;
public class MainActivity extends FlutterActivity {
private static final String CHANNEL = "dev.dhanraj.kwgt.test.dashboard";
#Override
public void configureFlutterEngine(#NonNull FlutterEngine flutterEngine) {
super.configureFlutterEngine(flutterEngine);
new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL)
.setMethodCallHandler(
(call, result) -> {
// Note: this method is invoked on the main thread.
if (call.method.equals("enable")) {
ContextWrapper aContext = new ContextWrapper(getApplicationContext());
aContext.getPackageManager().setComponentEnabledSetting(new android.content.ComponentName(aContext, "org.kustom.api.Provider"), android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 1);
result.success(null);
Toast.makeText(this, "Done", Toast.LENGTH_SHORT).show();
} else{
result.notImplemented();
}
}
);
}
}

How to add a splash image to an adobe air for android application?

I need to add a preloader / splash screen to an Adobe Air application that I am building in IntelliJ Idea using pure Actionscript.
I have found many solutions, but they all assume a flex application. I am using the flex compiler, but the project is not written in flex so there are no mxml tags in order to use SparkMobileSplashScreen.mxml
Can a splash screen image be added to the air application xml file somehow?
Here's a basic setup for an embedded preloader. Your Document Class should look like this:
package {
import flash.display.Sprite;
[Frame(factoryClass='Preloader')] //class name of your preloader
public class Main extends Sprite {
public function Main() {
//init
}
}
}
Preloader Class:
package {
import flash.display.DisplayObject;
import flash.display.MovieClip;
import flash.events.ProgressEvent;
import flash.utils.getDefinitionByName;
public class Preloader extends MovieClip {
public function Preloader()
{
//add preloader graphics
//check loading progress
this.loaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgress);
}
private function onProgress(e:ProgressEvent):void
{
var percent:Number = Math.round(e.bytesLoaded / e.bytesTotal * 100);
if (percent == 100)
{
this.loaderInfo.removeEventListener(ProgressEvent.PROGRESS, onProgress);
onLoaded();
}
}
private function onLoaded():void
{
nextFrame(); //go to next frame
var App:Class = getDefinitionByName("Main") as Class; //class of your app
addChild(new App() as DisplayObject);
}
}
}

How can I access neo4j running on ( any http or localhost) from android

I am successfully implemented neo4j on both mac and java application but I cannot access the same from and android and the it crashes at dbpath.But it keeps crashing.How can I get it to work?
INstead of
graphDb = new EmbeddedGraphDatabase(DB_PATH);
it is
RestAPI graphDb = new RestAPIFacade("http://localhost:7474/db/data");
also tried
GraphDatabaseService graphDb=new RestGraphDatabase(“http://localhost:7474/db/data”);
Entire Code:
import java.io.File;
import java.io.IOException;
import org.neo4j.graphdb.Direction;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.RelationshipType;
import org.neo4j.graphdb.Transaction;
import org.neo4j.kernel.EmbeddedGraphDatabase;
import org.neo4j.kernel.impl.util.FileUtils;
public class EmbeddedNeo4j {
private static final String DB_PATH = "/home/User/Documents/neo4j/";
String greeting;
// START SNIPPET: vars
GraphDatabaseService graphDb;
Node firstNode;
Node secondNode;
Relationship relationship;
// END SNIPPET: vars
// START SNIPPET: createReltype
private static enum RelTypes implements RelationshipType {
KNOWS
}
// END SNIPPET: createReltype
public static void main(final String[] args) {
EmbeddedNeo4j hello = new EmbeddedNeo4j();
hello.createDb();
hello.removeData();
hello.shutDown();
}
void createDb() {
clearDb();
// START SNIPPET: startDb
graphDb = new EmbeddedGraphDatabase(DB_PATH);
registerShutdownHook(graphDb);
// END SNIPPET: startDb
// START SNIPPET: transaction
Transaction tx = graphDb.beginTx();
try {
// Mutating operations go here
// END SNIPPET: transaction
// START SNIPPET: addData
firstNode = graphDb.createNode();
firstNode.setProperty("message", "Hello, ");
secondNode = graphDb.createNode();
secondNode.setProperty("message", "World!");
relationship = firstNode.createRelationshipTo(secondNode,
RelTypes.KNOWS);
relationship.setProperty("message", "brave Neo4j ");
// END SNIPPET: addData
// START SNIPPET: readData
System.out.print(firstNode.getProperty("message"));
System.out.print(relationship.getProperty("message"));
System.out.print(secondNode.getProperty("message"));
// END SNIPPET: readData
greeting = ((String) firstNode.getProperty("message"))
+ ((String) relationship.getProperty("message"))
+ ((String) secondNode.getProperty("message"));
// START SNIPPET: transaction
tx.success();
} finally {
tx.finish();
}
// END SNIPPET: transaction
}
private void clearDb() {
try {
FileUtils.deleteRecursively(new File(DB_PATH));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
void removeData() {
Transaction tx = graphDb.beginTx();
try {
// START SNIPPET: removingData
// let's remove the data
firstNode.getSingleRelationship(RelTypes.KNOWS, Direction.OUTGOING)
.delete();
firstNode.delete();
secondNode.delete();
// END SNIPPET: removingData
tx.success();
} finally {
tx.finish();
}
}
void shutDown() {
System.out.println();
System.out.println("Shutting down database ...");
// START SNIPPET: shutdownServer
graphDb.shutdown();
// END SNIPPET: shutdownServer
}
// START SNIPPET: shutdownHook
private static void registerShutdownHook(final GraphDatabaseService graphDb) {
// Registers a shutdown hook for the Neo4j instance so that it
// shuts down nicely when the VM exits (even if you "Ctrl-C" the
// running example before it's completed)
Runtime.getRuntime().addShutdownHook(new Thread() {
#Override
public void run() {
graphDb.shutdown();
}
});
}
// END SNIPPET: shutdownHook
}
EmbeddedGraphDatabase can only be used if the DB and your client code should reside in the same JVM (therefore the word 'embedded').
If you want to remote access a Neo4j server the best ways today is either communicating with the transactional Cypher endpoint directly or using the Neo4j JDBC driver. Please note, in both cases you use Cypher to interact with the graph.
The library for java rest bindings is originated in the days where the two mentioned approached where not yet in place - so java-rest-bindings will be deprecated in the future.

Unable to retrieve Google Drive files and folders using new Drive API

I am trying to get a list of Files in a Folder from Google Drive from my Android app but have been unsuccessful so far. I'm using google-api-drive-v1-rev4-java-1.6.0-beta and google-api-client-1.9.0. I'm also building my code similar to calendar-android-sample and tasks-android-sample from the samples at http://code.google.com/p/google-api-java-client/wiki/Android.
I cant seem to find how to use files() to get a list of folders or even the id of the folder I want. The tasks-android-sample uses '#default' in the get() method to get a list of tasks. What would I use in the get method to get a list of folders first, search for my folder, get the id, then get a list of files in that folder?
AsyncLoadDocs.java: (Note: I'm using getFields() just to see if the Get object contains any metadata, which at this point doesn't.)
package com.mysite.myapp.docs;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.Drive.Files;
import com.google.api.services.drive.Drive.Files.Get;
import com.google.api.services.drive.model.File;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.ArrayAdapter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Asynchronously load the docs with a progress dialog.
*
* #author ms
*/
class AsyncLoadDocs extends AsyncTask<Void, Void, List<String>> {
private static final String TAG = "AsyncLoadDocs";
private final GDocsSync gDocsSync;
private final ProgressDialog dialog;
private final Drive entry = null;
private com.google.api.services.drive.Drive service;
AsyncLoadDocs(GDocsSync gDocsSync) {
this.gDocsSync = gDocsSync;
service = gDocsSync.driveClient;
dialog = new ProgressDialog(gDocsSync);
}
#Override
protected void onPreExecute() {
dialog.setMessage("Loading docs...");
dialog.show();
}
#Override
protected List<String> doInBackground(Void... arg0) {
try {
List<String> folderNames = new ArrayList<String>();
Get get = service.files().get("#default").setProjection("FULL");
String fields = get.getFields();
Log.d(TAG, "Fields: " + fields);
return folderNames;
} catch (IOException e) {
gDocsSync.handleGoogleException(e);
return Collections.singletonList(e.getMessage());
} finally {
gDocsSync.onRequestCompleted();
}
}
#Override
protected void onPostExecute(List<String> result) {
dialog.dismiss();
}
}
Any help would be appreciated. Both Calendar and Tasks samples successfully retrieve data from Google using my API key, why doesn't this Drive code?
The Drive API grants access only to two classes of files:
Files that a user has created with a given Drive app
Files that a user opens with a given Drive app
For security reasons, there's no method to list all files in a user Drive account:
https://developers.google.com/drive/apps_overview#granting_file-level_access
For more options in the Android environment, check out these other answers:
Android API for Google Drive?
Google Drive\Docs API for Android

Issue with loading local javascript files inside a webview

I had with an issue that has plagued me for days. It turned out that it was an Android glitch and has been submitted, confirmed, and hopefully will be fixed in a future release. Now I have found a solution that works for me, and will provide it below, however the solution is not perfect as it involves editing the phone gap source. Mainly my question is if someone can find a better solution to this issue.
The Bug:
There is a glitch when you attempt to load a page inside of a WebView on Android 3.0+. The glitch is that if that page references any local javascript files, you cannot append query data to the url. Basically
This works:
<script type="text/javascript" src="StaticJS.js"></script>
This does not work:
<script type="text/javascript" src="StaticJS.js?var=val"></script>
Why the hell would anyone want to do this since the file obviously can't do anything with the query vals? Well for me I have a phonegap application that loads a settings file via JSONP, however if a settings file is not specified it defaults to a local file. So yeah, the file can't process the query data but it would be nice to use the same file format and loading structure.
Solution 1 (Non-PhoneGap)
So there is an easy solution to this if the target android platform is 11(Honeycomb) or higher. (As long as you are careful and do not use any method that do not exists in any lower API levels this code will run on <11 apis, but you will still have to set 11 as your target)
Basically you add a WebViewClient to the WebView that utilizes the shouldInterceptRequest method to intercept the loading of local js files with query data attached.
import java.io.IOException;
import java.io.InputStream;
import android.content.res.AssetManager;
import android.webkit.WebResourceResponse;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class PatchingWebViewClient extends WebViewClient{
AssetManager am;
public PatchingWebViewClient(AssetManager am){
this.am = am;
}
#Override
public WebResourceResponse shouldInterceptRequest (WebView view, String url){
if(url.indexOf("file:///android_asset") == 0 && url.contains("?")){
String filePath = url.substring(22, url.length());
filePath = filePath.substring(0, filePath.indexOf("?"));
try {
InputStream is = am.open(filePath);
WebResourceResponse wr = new WebResourceResponse("text/javascript", "UTF-8", is);
return wr;
} catch (IOException e) {
return null;
}
}else{
return null;
}
}
}
To set the WebViewClient, your code would look something like this:
import android.app.Activity;
import android.os.Bundle;
import android.webkit.WebView;
public class CanWeBreakAWebViewActivity extends Activity {
WebView mWebView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mWebView = (WebView) findViewById(R.id.webview);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.setWebViewClient(new PatchingWebViewClient(this.getAssets()));
mWebView.loadUrl("file:///android_asset/index.html");
}
}
Solution 2 (PhoneGap)
Now for Phonegap I don't have a clean solution. My solution is to go and download the Phonegap source and edit the CordovaWebViewClient by adding the following method:
#Override
public WebResourceResponse shouldInterceptRequest (WebView view, String url){
if(url.indexOf("file:///android_asset") == 0 && url.contains("?")){
String filePath = url.substring(22, url.length());
filePath = filePath.substring(0, filePath.indexOf("?"));
try {
InputStream is = ctx.getAssets().open(filePath);
WebResourceResponse wr = new WebResourceResponse("text/javascript", "Cp1252", is);
return wr;
} catch (IOException e) {
return null;
}
}else{
return null;
}
}
Solution 3 (Non-Existent)
This solution would hopefully be some easy to include class or tweak to the main activity so that you can use phone gap but could just use a .jar file of the code, making upgrades easier.
Thanks for this post, you clued me in to the latest solution which is simply to use IceCreamCordovaWebViewClient.
#Override
public void init() {
super.init(webView, new IceCreamCordovaWebViewClient(this, webView), new CordovaChromeClient(this, webView));
}
Query data is appended to javascript files (and other file types like css) to prevent browser caching. The query data is useless to the file but the browser treats it as new because the location is changed (in the eyes of the browser) and it loads a fresh copy.
I'm glad you found an answer to your problem, just thought I'd give my input as to why people use this method.

Categories

Resources