I recently had a problem (seems to be a very common one [1][2][3]) when building a hybrid HTML5 mobile app. As can be seen in this online demo (https://mobilehtml5.org/ts/?id=23), one can use the input html tag with
type=”file” accept=”image/*”
to quickly and easily bring up the user’s camera if they visit the site from a mobile web browser like Chrome. But, embed the above in an Android webview and… nothing. We could fiddle around with intents and Java – Javascript bridges, but there has to be an easier way. Reading through some solutions someone suggested simply replacing the webview with one that actually works consistently.
The original suggestion pointed towards an “Android Advanced Webview” by a company named “Delight”. It is an excellent piece of code:
https://github.com/delight-im/Android-AdvancedWebView
And now clicking on the input tag brings up the native android chooser, allowing a user to upload an image they had already taken. Good, but not perfect. Ideally we allow the user to choose if they would like to upload a saved image they already took, or allow them to choose the “camera” option and take a picture on the spot. Out of the box, Android Advanced Webview doesn’t support this [4]. Bummer.
But this solution reminded me of something similar I played with years ago: the Intel-funded Crosswalk Project. It has definitely matured and gotten a lot better since I last checked it out. It proved relatively simple to embed it in my native android framework by following their documentation:
Embedding the Crosswalk Project
Note: if you’re using Android Studio and maven/gradle, a much – very much – easier way of embedding Crosswalk can be found here:
Embedding Crosswalk in Android Studio [5]
That did the trick! Now clicking on the input tag gives the user a choice:
Almost there. In my case, clicking on the camera option didn’t do anything :(. After some debugging and logging the intents being passed around, I noticed the android subsystem complaining of “revoked permission” even though I had the appropriate CAMERA permission in my manifest file:
<uses-permission android:name=”android.permission.CAMERA” />
UPDATE: If you see only the “camcoder” option as in the screenshot above, adding the “android.permission.WRITE_EXTERNAL_STORAGE” resolved the issue
Since I’m using Android 6.x, the permission scheme has changed and now requires you to ask for user permission at runtime . Following that realization, the below did the trick:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
mLayout = findViewById(R.id.fullscreen_content); | |
if (ContextCompat.checkSelfPermission(mContext, | |
android.Manifest.permission.CAMERA) | |
!= PackageManager.PERMISSION_GRANTED) { | |
// Should we show an explanation? | |
if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) mContext, | |
android.Manifest.permission.CAMERA)) { | |
// Show an expanation to the user *asynchronously* — don't block | |
// this thread waiting for the user's response! After the user | |
// sees the explanation, try again to request the permission. | |
Snackbar.make(mLayout, "Camera access is required to attach pictures to tasks.", | |
Snackbar.LENGTH_INDEFINITE).setAction("OK", new View.OnClickListener() { | |
@Override | |
public void onClick(View view) { | |
// Request the permission | |
ActivityCompat.requestPermissions(FullscreenActivity.this, | |
new String[]{android.Manifest.permission.CAMERA}, | |
159); | |
} | |
}).show(); | |
} else { | |
// No explanation needed, we can request the permission. | |
ActivityCompat.requestPermissions((Activity)mContext, | |
new String[]{android.Manifest.permission.CAMERA}, | |
159); | |
// 159 is an app-defined int constant. The callback method gets the | |
// result of the request. | |
} | |
} |
References
[1] http://stackoverflow.com/questions/18568566/webview-input-of-type-file-camera-and-image
[4] https://github.com/delight-im/Android-AdvancedWebView/issues/10
[5] Reproduced here: https://docs.google.com/document/d/15Lhg8de6hXmv0FVImu5OuWeqF1Dx5rcWUI0Hi08E78s/edit?usp=sharing
You must be logged in to post a comment.