Re: Input type = "file" button disabled in ICS / Phonegap 2.2

1,276 views
Skip to first unread message
Message has been deleted

Mike Britton

unread,
Dec 21, 2012, 3:35:05 PM12/21/12
to phon...@googlegroups.com
/*
       Licensed to the Apache Software Foundation (ASF) under one
       or more contributor license agreements.  See the NOTICE file
       distributed with this work for additional information
       regarding copyright ownership.  The ASF licenses this file
       to you under the Apache License, Version 2.0 (the
       "License"); you may not use this file except in compliance
       with the License.  You may obtain a copy of the License at


       Unless required by applicable law or agreed to in writing,
       software distributed under the License is distributed on an
       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
       KIND, either express or implied.  See the License for the
       specific language governing permissions and limitations
       under the License.
 */

package com.ggv.GGVAndroidWrapper;

import android.app.Activity;
import android.os.Bundle;
import org.apache.cordova.*;
import org.apache.cordova.api.*;

import android.util.Log;
import android.webkit.ValueCallback;
import android.widget.Toast;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;

public class GGVAndroidWrapper extends DroidGap
{
private ValueCallback<Uri> mUploadMessage;
    private final static int FILECHOOSER_RESULTCODE = 1;
    private FileAttachmentChromeClient chromeClient;
    
    
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        super.loadUrl("http://SOME_EXTERNAL_HTML?8");
        
        this.chromeClient = new FileAttachmentChromeClient(this, this.appView);
        this.appView.setWebChromeClient(this.chromeClient);
       
    }
    
    
@Override
protected void onActivityResult(int requestCode, int resultCode,
Intent intent) {
if (requestCode == FILECHOOSER_RESULTCODE) {
    Context context = getApplicationContext();
    CharSequence text = "requestCode: "+requestCode;
    int duration = Toast.LENGTH_SHORT;

    Toast toast = Toast.makeText(context, text, duration);
    toast.show();
   
   
        }
super.onActivityResult(requestCode, resultCode, intent);
}

    public class FileAttachmentChromeClient extends CordovaChromeClient {

        public FileAttachmentChromeClient(CordovaInterface ctx, CordovaWebView app) {
            super(ctx, app);

        }

        // For Android > 3.x
        public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
       
        // Here's where we take over for file uploads.
       
        // Send intent to open file chooser 
            mUploadMessage = uploadMsg;
            Intent i = new Intent(Intent.ACTION_GET_CONTENT);
            i.addCategory(Intent.CATEGORY_OPENABLE);
            i.setType("image/*");

            GGVAndroidWrapper.this.startActivityForResult(Intent.createChooser(i, "Choose type of attachment"), FILECHOOSER_RESULTCODE);
            
        }
        


    }    
    
    
}


On Wednesday, December 19, 2012 8:40:21 PM UTC-5, Mike Britton wrote:
I need an input type=file web form element to open the file browser and return to the code with the selected file to be submitted.  I accomplished this in a standard web form and tested in Android's regular browser, but when I wrap the app with Phonegap the button no longer works.

What is the workaround for this?  It seems like a lot of people are passing around an example where the camera is used, but I don't need the camera, I need a file browser.

Thanks in advance!!


Mike

Simon MacDonald

unread,
Dec 21, 2012, 3:45:09 PM12/21/12
to phonegap
Hey Mike,

I've successfully been able to get the file chooser up to pick a file
and when I return the file path to the HTML side it seems to be set
correctly but when I asked for input.value in JavaScript I only get
the file name. Have you been able to get the full path in your HTML?

Simon Mac Donald
http://hi.im/simonmacdonald


On Fri, Dec 21, 2012 at 3:32 PM, Mike Britton <mbrit...@gmail.com> wrote:
> I've managed to regain the ability to open the file chooser, and potentially
> do something with the file, in my main DroidGap activity. Now the problem
> is the button that launches the fileChooser only does it once! I can't
> reestablish the listener. This seems like a scope issue, but it's turning
> out to be such a pain in the ass I'm going with a native solution.
> //super.setIntegerProperty( "splashscreen", R.drawable.splash );
> //super.loadUrl("file:///android_asset/www/index.html");
>
> super.loadUrl("http://www.randomusa.com/elgg/tests/file_upload_test.html?8");
> //super.loadUrl("http://www.randomusa.com/elgg");
> //super.loadUrl("http://127.0.0.1:8888/elgg/index.php");
> //super.loadUrl("file:///android_asset/www/index.html");
> // this.appView.setWebChromeClient(new
> FileAttachmentChromeClient(this, this.appView));
>
> this.chromeClient = new FileAttachmentChromeClient(this,
> this.appView);
> this.appView.setWebChromeClient(this.chromeClient);
>
> }
>
>
>
> /* (non-Javadoc)
> * @see org.apache.cordova.DroidGap#onActivityResult(int, int,
> android.content.Intent)
> */
> @Override
> protected void onActivityResult(int requestCode, int resultCode,
> Intent intent) {
> if (requestCode == FILECHOOSER_RESULTCODE) {
> /*
> if (null == mUploadMessage) return;
> Uri result = intent == null || resultCode != RESULT_OK ? null :
> intent.getData();
> mUploadMessage.onReceiveValue(result);
> mUploadMessage = null;
> */
> Context context = getApplicationContext();
> CharSequence text = "requestCode: "+requestCode;
> int duration = Toast.LENGTH_SHORT;
>
> Toast toast = Toast.makeText(context, text, duration);
> toast.show();
>
> this.appView.setWebChromeClient(this.chromeClient);
> }
> super.onActivityResult(requestCode, resultCode, intent);
> }
>
> public class FileAttachmentChromeClient extends CordovaChromeClient {
>
> public FileAttachmentChromeClient(CordovaInterface ctx,
> CordovaWebView app) {
> super(ctx, app);
>
> }
>
> // For Android > 3.x
> public void openFileChooser(ValueCallback<Uri> uploadMsg, String
> acceptType) {
>
> // Here's where we take over for file uploads.
>
> // Send intent to open file chooser
> mUploadMessage = uploadMsg;
> Intent i = new Intent(Intent.ACTION_GET_CONTENT);
> i.addCategory(Intent.CATEGORY_OPENABLE);
> i.setType("image/*");
>
>
> GGVAndroidWrapper.this.startActivityForResult(Intent.createChooser(i,
> "Choose type of attachment"), FILECHOOSER_RESULTCODE);
>
> }
>
>
>
> }
>
>
> }
>
> --
> -- You received this message because you are subscribed to the Google
> Groups "phonegap" group.
> To post to this group, send email to phon...@googlegroups.com
> To unsubscribe from this group, send email to
> phonegap+u...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/phonegap?hl=en?hl=en
>
> For more info on PhoneGap or to download the code go to www.phonegap.com
>
> To compile in the cloud, check out build.phonegap.com
>
>

Mike Britton

unread,
Dec 21, 2012, 5:26:13 PM12/21/12
to phon...@googlegroups.com
Hi Simon.

I'm not even there yet.  My Phonegap WebView loads an external URL I've whitelisted.  Using the above technique, I can get the chooser via an Intent, but I can't set focus back on my web form once the file has been chosen.  Is this something you've achieved?

Thanks in advance if you can show me how you did this :)

Simon MacDonald

unread,
Dec 22, 2012, 10:05:55 AM12/22/12
to phonegap
I pushed up my code to a branch here:

https://github.com/macdonst/cordova-android/tree/fileinput

It is working pretty good except when I do:

document.getElementById("fp").value;

where "fp" is the id of the input field of type file I only get the
file name and not the full file path.

Almost there....
Simon Mac Donald
http://hi.im/simonmacdonald


Mike Britton

unread,
Dec 22, 2012, 9:37:36 PM12/22/12
to phon...@googlegroups.com
Don't know if this can help you since I've gone the native route for this, but I wriggled my way into getting the file path, extension and mime type in onActivityResult(). I could bang Google right now I'm so happy.

This is from a file chooser selection on all openable resources on the SD card.  I'm passing the path with the start activity intent.

@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

Log.d("result code: ", " " + resultCode);


Uri uri = data.getData();

String[] proj = { MediaStore.Images.Media.DATA };

Cursor cursor = getContentResolver().query(uri, proj, null, null, null);

int column_index = cursor

.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);

cursor.moveToFirst();

Log.d("Complete File Path ", "" + cursor.getString(column_index));


Intent sharePageIntent = new Intent(this, ShareActivity.class);

sharePageIntent.putExtra(FILE_PATH, cursor.getString(column_index));

startActivity(sharePageIntent);


super.onActivityResult(requestCode, resultCode, data);

}

I moved away from staying in Cordova, since my HTML is web-based and not compiled into the application.  I'm not sure, but I don't think it's possible for a remote web application to do things like call Phonegap plugins.  If I'm wrong, which I hope I am, at least I'll have this native piece.

Simon MacDonald

unread,
Dec 24, 2012, 9:55:46 AM12/24/12
to phonegap
Yeah, I'm in the same boat as you. In onActivityResult I have all the
information I need including the file path, mime type, etc. but when I
call

mUploadMessage.onReceiveValue(result);

in order to update the input tag in the HTML it does not get set
correctly. I need to look into what is happening there a bit more and
see if there is anyway I can update it manually.

Simon Mac Donald
http://hi.im/simonmacdonald


Mike Britton

unread,
Dec 24, 2012, 3:31:12 PM12/24/12
to phon...@googlegroups.com
Just as I finished a native version, I got uploads working in WebView.  Hope this helps.  It's undocumented, strictly speaking.


Java:


package com.ggv.GGVAndroidWrapper;

import java.util.Random;

import android.app.ActionBar;
import android.app.Activity;
import android.os.Bundle;
import org.apache.cordova.*;
import org.apache.cordova.api.*;

import android.util.Log;
import android.webkit.ValueCallback;
import android.widget.Toast;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;

public class GGVAndroidWrapper extends DroidGap {

private ValueCallback<Uri> mUploadMessage;
private final static int FILECHOOSER_RESULTCODE = 1;
private FileAttachmentChromeClient chromeClient;

@Override
public void onCreate(Bundle savedInstanceState) {
Random generator = new Random();
int r = generator.nextInt();

super.setBooleanProperty("showTitle", true);

super.onCreate(savedInstanceState);

super.setBooleanProperty("loadInWebView", true);

+ r);

this.chromeClient = new FileAttachmentChromeClient(this, this.appView);
this.appView.setWebChromeClient(this.chromeClient);

}

@Override
protected void onActivityResult(int requestCode, int resultCode,
Intent intent) {

if (requestCode == FILECHOOSER_RESULTCODE) {
if (null == mUploadMessage) {
return; 
}
 
Uri result = intent == null || resultCode != RESULT_OK ? null : intent.getData();
mUploadMessage.onReceiveValue(result); 
mUploadMessage = null;
 

Context context = getApplicationContext();
CharSequence text = "requestCode: " + requestCode;
int duration = Toast.LENGTH_SHORT;

Toast toast = Toast.makeText(context, text, duration);
toast.show();

}

super.onActivityResult(requestCode, resultCode, intent);
}

public class FileAttachmentChromeClient extends CordovaChromeClient {

public FileAttachmentChromeClient(CordovaInterface ctx,
CordovaWebView app) {
super(ctx, app);

}

// For Android > 3.x
public void openFileChooser(ValueCallback<Uri> uploadMsg,
String acceptType) {

// Send intent to open file chooser
mUploadMessage = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");

GGVAndroidWrapper.this.startActivityForResult(
Intent.createChooser(i, "Choose type of attachment"),
FILECHOOSER_RESULTCODE);

}
}

}


HTML:

<html>


    <head>

        <title>File Upload Test Form</title>

        


        

        <script language="JavaScript" src="../js/lib/jquery-1.7.1.min.js"></script>


    </head>

    <body onload="init()">

        test page for JavaScript / Phonegap connectivity

        <p></p>

        

        

        <form method="POST" enctype="multipart/form-data" action="http://path/to/script/uploads.php">

        File to upload: <input type="file" name="upload">&nbsp;&nbsp;

        <input type="submit" value="Press to Upload..."> to upload the file!

        </form>                

    </body>

</html>


Mike Britton

unread,
Dec 24, 2012, 3:58:18 PM12/24/12
to phon...@googlegroups.com
Further clarification: the solution above is for Android 3.x and above. It needs to be in DroidGap, IMO.

Simon MacDonald

unread,
Dec 24, 2012, 4:26:12 PM12/24/12
to phonegap
If you look at the branch I posted you'll see I integrated it into DroidGap/CordovaWebView/CordovaChromeClient. I'm able to get the value back to the input tag but on 2.x it only gives me the file name while on 3.x+ it gives me something like this:

12-24 17:17:56.948: D/CordovaLog(4849): result = C:\fakepath\1352731741721.jpg
12-24 17:17:56.948: D/CordovaLog(4849): files = [object FileList]
12-24 17:17:56.978: D/CordovaLog(4849): [0] {"size":2422528,"lastModifiedDate":"2012-11-12T13:49:00.000Z","fileSize":2422528,"name":"1352731741721.jpg","type":"image/jpeg","fileName":"1352731741721.jpg"}

So things are being set correctly but I'd like to see the real path to the file in there somewhere. 

If you want I can send you a .jar/.js combo for you to test with your upload script. Lemme know...


On Mon, Dec 24, 2012 at 3:58 PM, Mike Britton <mbrit...@gmail.com> wrote:
Further clarification:  the solution above is for Android 3.x and above.  It needs to be in DroidGap, IMO.

Mike Britton

unread,
Dec 25, 2012, 12:34:34 AM12/25/12
to phon...@googlegroups.com
Using ICS, I'm seeing the file name only in the input tag. Default browser.

Simon MacDonald

unread,
Jan 17, 2013, 11:00:01 PM1/17/13
to phonegap
I pushed my code to the Android repo today. Joe made some tweaks and basic support will be in 2.4.0.

On Tue, Dec 25, 2012 at 12:34 AM, Mike Britton <mbrit...@gmail.com> wrote:
Using ICS, I'm seeing the file name only in the input tag.  Default browser.
Reply all
Reply to author
Forward
0 new messages