google maps - show current position coordinates - maps

I want to show coordinates from my current position on map. Here is the code and it doesn't work like it should. It only shows map within defined parameters, but when I click on button that shows my current position, nothing happens.
I made this code using Android Studio tutorials on web.
I am using Android studio and just a fresh learner.
This is also what I get in event log when I run the app on my smartphone:
21:56:48 Can't bind to local 8600 for debugger
21:56:49 An established connection was aborted by the software in your host machine
java.io.IOException: An established connection was aborted by the software in your host machine
at sun.nio.ch.SocketDispatcher.write0(Native Method)
at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:51)
at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93)
at sun.nio.ch.IOUtil.write(IOUtil.java:65)
at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:487)
at com.android.ddmlib.JdwpPacket.writeAndConsume(JdwpPacket.java:213)
at com.android.ddmlib.Client.sendAndConsume(Client.java:686)
at com.android.ddmlib.HandleHeap.sendREAQ(HandleHeap.java:349)
at com.android.ddmlib.Client.requestAllocationStatus(Client.java:525)
at com.android.ddmlib.DeviceMonitor.createClient(DeviceMonitor.java:569)
at com.android.ddmlib.DeviceMonitor.openClient(DeviceMonitor.java:544)
at com.android.ddmlib.DeviceMonitor.deviceClientMonitorLoop(DeviceMonitor.java:360)
at com.android.ddmlib.Devic...
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="#string/google_maps_key" />
<activity
android:name=".MapsActivity_koordinate"
android:label="#string/title_activity_maps">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
</application>
package com.example.apollo.kartamackovec;
import android.location.Location;
import android.net.Uri;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.appindexing.Action;
import com.google.android.gms.appindexing.AppIndex;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
public class MapsActivity_koordinate extends FragmentActivity implements GoogleApiClient.ConnectionCallbacks,GoogleApiClient.OnConnectionFailedListener, OnMapReadyCallback, MapsActivity {
public GoogleMap mMap;
public GoogleApiClient client;
public TextView mLongitudeText;
public TextView mLatitudeText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
LatLng mackovec = new LatLng(46.4239, 16.4339);
mMap.addMarker(new MarkerOptions().position(mackovec).title("Marker u Mačkovcu"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(mackovec));
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(mackovec, 18));
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
mMap.setMyLocationEnabled(true);
}
#Override
public void onConnected(Bundle connectionHint) {
Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation(client);
if (mLastLocation != null) {
mLatitudeText.setText(String.valueOf(mLastLocation.getLatitude()));
mLongitudeText.setText(String.valueOf(mLastLocation.getLongitude()));
Toast.makeText(this, "Location " + mLatitudeText+","+mLongitudeText,
Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, "noconnection",
Toast.LENGTH_LONG).show();
}
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onStart() {
client.connect();
super.onStart();
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
client.connect();
Action viewAction = Action.newAction(
Action.TYPE_VIEW, // TODO: choose an action type.
"Main Page", // TODO: Define a title for the content shown.
// TODO: If you have web page content that matches this app activity's content,
// make sure this auto-generated web page URL is correct.
// Otherwise, set the URL to null.
Uri.parse("http://host/path"),
// TODO: Make sure this auto-generated app deep link URI is correct.
Uri.parse("android-app://com.example.apollo.kartamackovec/http/host/path")
);
AppIndex.AppIndexApi.start(client, viewAction);
}
#Override
public void onStop() {
client.disconnect();
super.onStop();
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
Action viewAction = Action.newAction(
Action.TYPE_VIEW, // TODO: choose an action type.
"Main Page", // TODO: Define a title for the content shown.
// TODO: If you have web page content that matches this app activity's content,
// make sure this auto-generated web page URL is correct.
// Otherwise, set the URL to null.
Uri.parse("http://host/path"),
// TODO: Make sure this auto-generated app deep link URI is correct.
Uri.parse("android-app://com.example.apollo.kartamackovec/http/host/path")
);
AppIndex.AppIndexApi.end(client, viewAction);
client.disconnect();
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Toast.makeText(this, "noconnection",
Toast.LENGTH_LONG).show();
}
}

Related

I want to run different classes particular method from TestNG but everytime it opens a new window when i include beforeclass in each class

I want to run different classes particular method from TestNG but everytime it opens a new window when i include beforeclass in each class so i have now excluded beforeclass from add and logout classes so it can use same browser to run rest methods but its not working
The first class is of login class which is as below
public class LoginWeb {
public WebDriver driver;
WebDriverWait wait;
LoginScreen loginExcel;
#BeforeClass
public void beforeClass (){
System.setProperty("webdriver.chrome.driver", "D:\\chromedriver.exe");
driver=new ChromeDriver();
driver.manage().window().maximize();
driver.get("http://10.7.1.180/views/index.html#/login");
System.out.println(driver.getTitle());
}
#Test (description = "Valid Credentials!")
public void LoginWithValidWebExcelEmailAndPass() throws IOException, BiffException {
loginExcel= new LoginScreen(driver);
FileInputStream fi = new FileInputStream("D:\\Programs\\New\\Sourcesmartdata.xls");
Workbook w = Workbook.getWorkbook(fi);
Sheet s = w.getSheet(0);
int z = s.getRows();
System.out.println("no of rows------------------------:"+z);
String email = s.getCell(0, 1).getContents();
System.out.println("Email -----------------"+email);
loginExcel.EnterEmail(email);
String password= s.getCell(1, 1).getContents();
System.out.println("Password------------------- "+password);
loginExcel.EnterPassword(password);
loginExcel.ClickToLogin();
wait= new WebDriverWait(driver, 10);
WebElement GetLogo = wait.until(ExpectedConditions.visibilityOf(loginExcel.TopRightMenu));
String str= GetLogo.getText();
System.out.println("Text------------"+str);
Assert.assertEquals(str, "Source Smart");
}
}
The second class is of adding commodities here i have excluded beforeclass as if i include before class it opens a new window and here login script is not written
public class AddCommoditiesWeb{
WebDriver driver;
WebDriverWait wait;
AddCommodities addcommodity;
#Test (description="Add Multiple Commodities!")
public void AddMultipleNewCommodities () throws Exception, Exception{
addcommodity = new AddCommodities(driver);
addcommodity.MenuCommodities(); //click left menu to open manage commodities page
FileInputStream fi = new FileInputStream("D:\\Programs\\New\\Sourcesmartdata.xls");
Workbook w = Workbook.getWorkbook(fi);
Sheet s = w.getSheet(1);
int z=s.getRows();
System.out.println("no of rows------------------------:"+z);
for(int row=1; row <2; row++){
Thread.sleep(5000);
addcommodity.ClickAddCommodities(); // click add commodity button
String commodityname = s.getCell(0, row).getContents();
System.out.println("commodityname -----------------"+commodityname);
//enterdefinecommodityTxtBox.sendKeys(commodityname);
addcommodity.Enterdefinecommodity(commodityname);
String grade= s.getCell(1, row).getContents();
System.out.println("grade------------------- "+grade);
//entergradeTxtBox.sendKeys(grade);
String unit= s.getCell(2, row).getContents();
System.out.println("unit------------------- "+unit);
//enterunitTxtBox.sendKeys(unit);
String minprice= s.getCell(3, row).getContents();
System.out.println("min price------------------- "+minprice);
//enterminpriceTxtBox.sendKeys(minprice);
String maxprice= s.getCell(4, row).getContents();
System.out.println("max price------------------- "+maxprice);
//entermaxpriceTxtBox.sendKeys(maxprice);
addcommodity.EnterAddCommoditiesData(grade,unit,minprice,maxprice);
}
wait=new WebDriverWait(driver,10);
WebElement commodityname= wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("/html/body/div/div[4]/div/section[2]/div[4]/d-expand-collapse[1]/div/div/div[1]/h4/a")));
String commoditynamejustadded= commodityname.getText();
System.out.println("name--------------"+commoditynamejustadded);
assertEquals(commoditynamejustadded, "Rice");
}
}
TestNG code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
<test name="Login check">
<classes>
<class name="SourceSmartWeb.LoginWeb"/>
<class name = "SourceSmartWeb.AddCommoditiesWeb">
<methods>
<include name="AddMultipleNewCommodities"/>
</methods>
</class>
<class name ="SourceSmartWeb.LogoutWeb"/>
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
Logout class:
public class LogoutWeb{
WebDriver driver;
// #BeforeClass
// public void beforeClass (){
// System.setProperty("webdriver.chrome.driver", "D:\\chromedriver.exe");
// driver=new ChromeDriver();
// driver.manage().window().maximize();
// driver.get("http://10.7.1.180/views/index.html#/login");
// System.out.println(driver.getTitle());
// super.beforeClass();
//
// }
#Test
public void Logout() throws InterruptedException {
LogoutScreen logout=new LogoutScreen(driver);
logout.ClickToLogout();
}
#AfterClass
public void exit(){
driver.quit();
}
}
What its doing is it opens the browser logins and then do nothing. How can i make it do rest of activities on same browser as if i add before class in second class it opens a new browser and then there i dont have login code. please guide
From what you are stating, it looks like you need to basically have a browser spawned per <test> tag and then share that browser amongst all your test classes. But you cannot make use of the #BeforeTest and #AfterTest annotations because you would need to bring in inheritance into the picture and since these methods are executed only once per <test> you will start seeing NullPointerException.
So the idea is to basically leverage TestNG listeners for this webdriver instantiation and cleanup and have your test classes/methods just query them from within a helper method.
Here's some sample code, that shows all of this in action.
Here's how the listener would look like
package com.rationaleemotions.stackoverflow.qn46239358;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.ITestContext;
import org.testng.ITestResult;
import org.testng.Reporter;
import org.testng.TestListenerAdapter;
public class WebdriverSpawner extends TestListenerAdapter {
private static final String WEBDRIVER = "webdriver";
#Override
public void onStart(ITestContext testContext) {
testContext.setAttribute(WEBDRIVER, createDriver());
}
#Override
public void onFinish(ITestContext testContext) {
getWebDriverFromContext(testContext).quit();
}
public static RemoteWebDriver getCurrentWebDriver() {
ITestResult result = Reporter.getCurrentTestResult();
if (result == null) {
throw new IllegalStateException("Please invoke this from within a #Test annotated method");
}
ITestContext context = result.getTestContext();
return getWebDriverFromContext(context);
}
private static RemoteWebDriver getWebDriverFromContext(ITestContext context) {
Object object = context.getAttribute(WEBDRIVER);
if (!(object instanceof RemoteWebDriver)) {
throw new IllegalStateException("Encountered problems in retrieving the webdriver instance");
}
return (RemoteWebDriver) object;
}
private static RemoteWebDriver createDriver() {
return new ChromeDriver();
}
}
Here's how your test classes which now use this above listener can look like (I have intentionally kept it simple and have it open up just a URL, but if you run them you would notice a single browser opening up multiple URLs. So only one browser instance)
package com.rationaleemotions.stackoverflow.qn46239358;
import org.testng.annotations.Test;
public class LoginWeb {
#Test(description = "Valid Credentials!")
public void LoginWithValidWebExcelEmailAndPass() {
System.err.println("Page title : " + PageLoader.loadAndGetTitle("http://www.google.com"));
}
}
package com.rationaleemotions.stackoverflow.qn46239358;
import org.testng.annotations.Test;
public class LogoutWeb {
#Test
public void Logout() throws InterruptedException {
System.err.println("Page title : " + PageLoader.loadAndGetTitle("http://www.facebook.com"));
}
}
package com.rationaleemotions.stackoverflow.qn46239358;
import org.testng.annotations.Test;
public class AddCommoditiesWeb {
#Test(description = "Add Multiple Commodities!")
public void AddMultipleNewCommodities() {
System.err.println("Page title : " + PageLoader.loadAndGetTitle("http://www.yahoo.com"));
}
#Test
public void anotherTestMethod() {
System.err.println("Page title : " + PageLoader.loadAndGetTitle("http://www.ndtv.com"));
}
}
The PageLoader utility class looks like this
package com.rationaleemotions.stackoverflow.qn46239358;
import org.openqa.selenium.remote.RemoteWebDriver;
public final class PageLoader {
private PageLoader() {
//Utility class defeat instantiation
}
public static String loadAndGetTitle(String url) {
RemoteWebDriver driver = WebdriverSpawner.getCurrentWebDriver();
driver.get(url);
return driver.getTitle();
}
}
Here's how the suite xml looks like :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="46216357_Suite" verbose="2">
<listeners>
<listener class-name="com.rationaleemotions.stackoverflow.qn46239358.WebdriverSpawner"/>
</listeners>
<test name="Login_check">
<classes>
<class name="com.rationaleemotions.stackoverflow.qn46239358.LoginWeb"/>
<class name="com.rationaleemotions.stackoverflow.qn46239358.AddCommoditiesWeb">
<methods>
<include name="AddMultipleNewCommodities"/>
</methods>
</class>
<class name="com.rationaleemotions.stackoverflow.qn46239358.LogoutWeb"/>
</classes>
</test>
</suite>
So here none of your #Test classes invoke driver.quit() explicitly. The webdriver cleanup is managed by the listener.
This model is going to work only when you want to run multiple tests on the same browser.
The flip side of this would be that, you can NEVER run your #Test methods in parallel, because now all your tests are sharing the same browser.

Unable to dispatch touch to JS as the catalyst instance has not been attached

I'm using react-native-share-extension for sharing images from gallery.
So I use two activities(MainActivity and ShareActivity).
But when ShareActivity is finished, there is no reaction from the main app.
All UI components are stopped.
Android monitor message says
"Unable to dispatch touch to JS as the catalyst instance has not been attached"
My code is below.
AndroidManifest.xml
<activity
android:noHistory="true"
android:name=".share.MyShareActivity"
android:configChanges="orientation"
android:label="#string/title_activity_share"
android:screenOrientation="portrait"
android:launchMode="standard"
android:theme="#style/Theme.Share.Transparent" >
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="*/*" />
</intent-filter>
</activity>
MyShareActivity.java
package com.mobileopenalm.share;
import android.app.Activity;
import android.os.Bundle;
import com.facebook.react.ReactActivity;
import com.github.alinz.reactNativeShareExtension.ShareExActivity;
import com.mobileopenalm.BuildConfig;
public class MyShareActivity extends ReactActivity {
static MyShareActivity myActivity = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myActivity = this;
}
#Override
protected String getMainComponentName() {
return "MyShareEx";
}
#Override
protected boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
static protected MyShareActivity getActivity(){
return myActivity;
}
}
InternalShare.java(declare reactMethod)
public class InternalShare extends ReactContextBaseJavaModule {
public InternalShare(ReactApplicationContext reactContext) {
super(reactContext);
}
#Override
public String getName() {
return "ShareExtension";
}
#ReactMethod
public void close() {
MyShareActivity.getActivity().finish();
}
#ReactMethod
public void data(Callback successCallback){
// WritableMap map = Arguments.createMap();
Intent intent = getCurrentActivity().getIntent();
String action = intent.getAction();
String type = intent.getType();
String[] value = null;
if (type == null) {
type = "";
}
//if you want to support more, just add more things here.
//at the moment we are only supporting browser URL
if (Intent.ACTION_SEND.equals(action)) {
ClipData c = intent.getClipData();
int count = c.getItemCount();
value = new String[count];
for(int i = 0; i < count ; i++){
value[i] = c.getItemAt(i).getUri().toString();
}
}
if(value == null){
successCallback.invoke("");
} else {
successCallback.invoke(value);
}
}
}
share.android.js - close method (Share extension starts here.)
onClose() {
// console.log(NativeModules.ShareExtension.data())
NativeModules.ShareExtension.close();
},
index.android.js
/**
* Sample React Native App
* https://github.com/facebook/react-native
*/
import Share from './share.android';
'use strict';
var { AppRegistry } = require('react-native');
var App = require('./App/App');
// var DropDownApp = require('./App/DropDown');
AppRegistry.registerComponent('mobileOpenAlm', () => App);
AppRegistry.registerComponent('MyShareEx', () => Share);
Details -
When I share photos from gallery, app redirected share.android.js.
And main app(mobileOpenAlm) go to background.
After using onClose() method at share.android.js, app closed successfully. But I went back to main app, app has not responding.
And log is below.
Unable to dispatch touch to JS as the catalyst instance has not been attached.
How can I fix this problem?

Google Analytics (V4) OnCreate Cannot cast from Application

I have followed a better tutorial than the google one to start to get analytics in my app.
The problem is that
package com.sgdva.ishikawa;
import com.google.android.gms.analytics.Tracker;
import com.google.android.gms.analytics.GoogleAnalytics;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import java.util.HashMap;
public class Ishikawa extends Activity {
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.sources, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.action_settings:
startActivity(new Intent(Ishikawa.this, Sources.class));
return true;
default:
return super.onOptionsItemSelected(item);
}
}
// The following line should be changed to include the correct property id.
private static final String PROPERTY_ID = "UA-50596309-1";
// Logging TAG
private static final String TAG = "Ishikawa";
public static int GENERAL_TRACKER = 0;
public enum TrackerName {
APP_TRACKER, // Tracker used only in this app.
GLOBAL_TRACKER, // Tracker used by all the apps from a company. eg:
// roll-up tracking.
ECOMMERCE_TRACKER, // Tracker used by all ecommerce transactions from a
// company.
}
HashMap<TrackerName, Tracker> mTrackers = new HashMap<TrackerName, Tracker>();
public Ishikawa() {
super();
}
synchronized Tracker getTracker(TrackerName trackerId) {
if (!mTrackers.containsKey(trackerId)) {
GoogleAnalytics analytics = GoogleAnalytics.getInstance(this);
Tracker t = (trackerId == TrackerName.APP_TRACKER) ? analytics
.newTracker(R.xml.app_tracker)
: (trackerId == TrackerName.GLOBAL_TRACKER) ? analytics
.newTracker(PROPERTY_ID) : analytics
.newTracker(R.xml.ecommerce_tracker);
mTrackers.put(trackerId, t);
}
return mTrackers.get(trackerId);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Get a Tracker (should auto-report)
((Ishikawa) getApplication())
.getTracker(Ishikawa.TrackerName.APP_TRACKER);
setContentView(R.layout.activity_ishikawa);
In this line
((Ishikawa) getApplication()).getTracker(Ishikawa.TrackerName.APP_TRACKER);
It says:Cannot cast from Application to Ishikawa
I have read that this is because my android name is not delcared in my manifest.xml but it is
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.sgdva.ishikawa"
android:versionCode="2"
android:versionName="1.1" >
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="18" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:name="com.sgdva.ishikawa.Ishikawa"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme"
>
<!-- Google Analytics Version v4 needs this value for easy tracking -->
<meta-data android:name="com.google.android.gms.analytics.globalConfigResource"
android:resource="#xml/global_tracker" />
<activity
android:name="com.sgdva.ishikawa.Ishikawa"
android:label="#string/app_name"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.sgdva.ishikawa.Machine"
android:label="#string/title_activity_machine"
android:screenOrientation="portrait" >
</activity>
<activity android:name="com.google.android.gms.ads.AdActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|s mallestScreenSize"/>
<meta-data android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<activity
android:name="com.sgdva.ishikawa.MainActivity"
android:label="#string/title_activity_main"
android:screenOrientation="portrait">
</activity>
</application>
</manifest>
Why would this happen?
It was my bad, I was calling my "activity" as an "application"
((Ishikawa) getApplication()).getTracker(Ishikawa.TrackerName.APP_TRACKER);
I made another .class called "Tracker.java" get the code for analytics there and referenced it instead:
((Tracker) getApplication()).getTracker(Tracker.TrackerName.APP_TRACKER);

GWT Fileupload, what event or handler when user click the choose file button

I am new to GWT/GAE.
To use GAE Blobstore service, a upload url must be returned from server side, as the tutorial in this blog .
But it seems this get upload url service can be called while user is browsing file, thus I need to find the event to handle when user press the choose file button, and set the formpanel's action attribute there.
fileupload itself has attach/detach or change event, but it seems not what i am looking for.
My code which can do upload to blobstore is as follow:
The upload form is:
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import com.google.gwt.cell.client.DateCell;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FileUpload;
import com.google.gwt.user.client.ui.FormPanel;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.FormPanel.SubmitCompleteHandler;
import com.google.gwt.user.client.ui.FormPanel.SubmitCompleteEvent;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.TextArea;
public class UploadFilePanel implements EntryPoint {
private FileServiceAsync upls = GWT.create(FileService.class);
AsyncCallback<String> callback;
FormPanel form;
String upload_url;
public void onModuleLoad() {
get_upload_url();
RootPanel rootPanel = RootPanel.get();
FlowPanel flowPanel = new FlowPanel();
rootPanel.add(flowPanel, 0, 0);
add_submit_form(flowPanel);
}
private void add_submit_form(FlowPanel flowPanel) {
VerticalPanel panel = new VerticalPanel();
flowPanel.add(panel);
// Create a FormPanel and point it at a service.
form = new FormPanel();
panel.add(form);
form.setEncoding(FormPanel.ENCODING_MULTIPART);
form.setMethod(FormPanel.METHOD_POST);
form.addSubmitCompleteHandler(new SubmitCompleteHandler() {
#Override
public void onSubmitComplete(SubmitCompleteEvent event) {
RootPanel.get().clear();
RootPanel.get().getElement()
.setInnerHTML("upload complete " + event.toString());
}
});
form.setSize("222px", "52px");
// Create a FileUpload widget.
FileUpload upload = new FileUpload();
form.setWidget(upload);
upload.setSize("100%", "100%");
upload.setName("myFile");
TextArea textArea = new TextArea();
panel.add(textArea);
textArea.setWidth("100%");
// Add a 'submit' button.
Button submitbtn = new Button("Submit");
panel.add(submitbtn);
submitbtn.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
upls.get_upload_url("/stmtgen/upload", callback);
}
});
}
private void get_upload_url() {
callback = new AsyncCallback<String>() {
#Override
public void onSuccess(String result) {
form.setAction(result);
upload_url = result;
form.submit();
}
#Override
public void onFailure(Throwable caught) {
RootPanel.get().clear();
RootPanel.get().getElement()
.setInnerHTML("Can't get upload url");
}
};
if (upls == null)
upls = GWT.create(FileService.class);
}
}
The Async service I used to get upload url is this:
import com.google.gwt.user.client.rpc.AsyncCallback;
public interface FileServiceAsync {
void get_upload_url(String up, AsyncCallback<String> callback);
}
The problem is when user hit submit button, there is two services invocation which slow down the response.
I tried addHandler(Handler, Type) as below, it doesn't work.
FileUpload upload = new FileUpload();
upload.addHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
//get upload url here
}
}, ClickEvent.getType()
);

JSF file upload on GAE

I'm trying to have a file upload element in my JSF over Google App Engine.
I have browsed the web for several alternatives but none seem to work with GAE.
I was able to do so using JSP and servlet with BlobstoreService but couldn't find a way to make it working with JSF.
As a workaround I was trying to see if there is a way to include a JSP within a JSF but I guess this isn't doable as well.
Would be thankful to get a working example.
Thanks!
First get library http://code.google.com/p/gmultipart/ and add to your project.
And than override class org.primefaces.webapp.filter.FileUploadFilter (just put in your src).
There is code of class org.primefaces.webapp.filter.FileUploadFilter:
package org.primefaces.webapp.filter;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.gmr.web.multipart.GFileItemFactory;
import org.primefaces.webapp.MultipartRequest;
public class FileUploadFilter implements Filter {
private final static Logger logger = Logger.getLogger(FileUploadFilter.class.getName());
private final static String THRESHOLD_SIZE_PARAM = "thresholdSize";
private final static String UPLOAD_DIRECTORY_PARAM = "uploadDirectory";
private String thresholdSize;
private String uploadDir;
public void init(FilterConfig filterConfig) throws ServletException {
thresholdSize = filterConfig.getInitParameter(THRESHOLD_SIZE_PARAM);
uploadDir = filterConfig.getInitParameter(UPLOAD_DIRECTORY_PARAM);
if(logger.isLoggable(Level.FINE))
logger.fine("FileUploadFilter initiated successfully");
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
boolean isMultipart = ServletFileUpload.isMultipartContent(httpServletRequest);
if(isMultipart) {
if(logger.isLoggable(Level.FINE))
logger.fine("Parsing file upload request");
//start change
FileItemFactory diskFileItemFactory = new GFileItemFactory();
/* if(thresholdSize != null) {
diskFileItemFactory.setSizeThreshold(Integer.valueOf(thresholdSize));
}
if(uploadDir != null) {
diskFileItemFactory.setRepository(new File(uploadDir));
}*/
//end change
ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory);
MultipartRequest multipartRequest = new MultipartRequest(httpServletRequest, servletFileUpload);
if(logger.isLoggable(Level.FINE))
logger.fine("File upload request parsed succesfully, continuing with filter chain with a wrapped multipart request");
filterChain.doFilter(multipartRequest, response);
} else {
filterChain.doFilter(request, response);
}
}
public void destroy() {
if(logger.isLoggable(Level.FINE))
logger.fine("Destroying FileUploadFilter");
}
}
In managed bean write method like:
public void handleFileUpload(FileUploadEvent event) {
UploadedFile uploadedFile = event.getFile();
try {
String blobKey = BlobUtils.uploadImageToBlobStore(uploadedFile.getContentType(), uploadedFile.getFileName(), uploadedFile.getContents());
this.iconKey = blobKey;
} catch (IOException e) {
log.log(Level.SEVERE, "Ошибка при попытке загрузить файл в blob-хранилище", e);
FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Ошибка при попытке загрузить файл", event.getFile().getFileName() + " не загружен!");
FacesContext.getCurrentInstance().addMessage(null, msg);
return;
}
FacesMessage msg = new FacesMessage("Успешно.", event.getFile().getFileName() + " загружен.");
FacesContext.getCurrentInstance().addMessage(null, msg);
}
And that all.
First of all , I think that whatever you are doing with JSP should eventually work with JSF as well..
BUT,
If you are looking for a file upload component for JSF , that works on GAE ,
take a look at the PrimeFaces FileUpload
Here is another link that got an explanation on what to do in order it to work on GAE :Primefaces File Upload Filter
(haven't tried it myself...)

Resources