I am using SQLite database for my PhoneGap project.The database is getting populated on every other OS I have tested except Android 4.4.0+ .
The Code for accessing database is below :-
public class MathWhiz extends CordovaActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.init();
super.loadUrl(Config.getStartUrl());
SharedPreferences sp = getSharedPreferences("MYPREFS",
Activity.MODE_PRIVATE);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
// If no shared prefs exist, e.g. first install, it doesn't matter - the
// following will return false as a default
Boolean database_copied = sp.getBoolean("database_copied", false);
if (!database_copied) {
try {
String pName = this.getClass().getPackage().getName();
this.copy("Databases.db", "/data/data/" + pName
+ "/app_database/");
this.copy("sample.db", "/data/data/" + pName
+ "/app_database/myFile/");
SharedPreferences.Editor editor = sp.edit();
editor.putBoolean("database_copied", true);
editor.apply();
} catch (IOException e) {
e.printStackTrace();
}
}
}
void copy(String file, String folder) throws IOException {
File CheckDirectory;
CheckDirectory = new File(folder);
if (!CheckDirectory.exists()) {
CheckDirectory.mkdir();
}
InputStream in = getApplicationContext().getAssets().open(file);
OutputStream out = new FileOutputStream(folder + file);
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0)
out.write(buf, 0, len);
in.close();
out.close();
}
}
And this is how I am using the database :-
window.openDatabase("sampleDB", "1.0", "sample", 200000);
Can anybody please point out what updates I need to do in order to make it work on Android 4.4 + ? Thanks
try it.. its working well...
public boolean copyDataBaseFromAssets(Context c) throws IOException {
if(android.os.Build.VERSION.SDK_INT >= 17)
DB_PATH = context.getApplicationInfo().dataDir + "/databases/"+ DATABASE_NAME;
else
DB_PATH = "/data/data/" + context.getPackageName() + "/databases/"+DATABASE_NAME;
String pathToDatabaseFileInAssetFolder = DATABASE_NAME;
String pathToDatabaseFileInSystem = DB_PATH;
this.getReadableDatabase();
> getReadableDatabase funcation used in db import code
AssetManager assetManager = c.getResources().getAssets();
InputStream inputStream = null;
try {
inputStream = assetManager.open(pathToDatabaseFileInAssetFolder);
} catch (IOException ex) {
return false;
}
if (inputStream != null) {
OutputStream outputStream = new FileOutputStream(pathToDatabaseFileInSystem);
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, length);
}
outputStream.flush();
outputStream.close();
inputStream.close();
Log.d(TAG, "Database is copied");
return true;
}
return false;
}
Change this
this.copy("Databases.db", "/data/data/" + pName + "/databases/");
this.copy("sample.db", "/data/data/" + pName + "/databases/");
Related
I'm trying to send a request to an API through (t = textToSpeechService.callAPI(tmp);) and it returns an audio file. I tried serving it to the front end through the OutputStream but how do I actually serve the actual file i.e. wav file, since I need it afterwards to play and pause in the front end?
public Clip callAPI(Source src){
URL url;
Clip result = null;
AudioInputStream sound = null;
{
try {
url = new URL(" http://api.voicerss.org/?key=" + keyAPI + "&hl=" + src.getLang() + "&src=" + src.getSrc());
sound = AudioSystem .getAudioInputStream(url); //here i have the audio
Object sound2 = AudioSystem.getAudioInputStream(url);
AudioFormat at = sound.getFormat();
result = AudioSystem.getClip();
result.open(sound);
} catch (MalformedURLException e) {
e.printStackTrace();
}catch (UnsupportedAudioFileException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}catch (LineUnavailableException e) {
e.printStackTrace();
}
}
return result;
}
Clip t = null;
AudioInputStream ais = null;
private TextToSpeechService textToSpeechService;
public Clip theFunction(#RequestParam String src, HttpServletRequest request){
//if(src == request.getSession().getAttribute("input")){
Source tmp = new Source();
tmp.setSrc(src);
t = textToSpeechService.callAPI(tmp);
t.start();
return t;
}
public void getHere(#RequestParam String src, HttpServletRequest request, HttpServletResponse response) throws IOException {
Source tmp = new Source();
tmp.setSrc(src);
ais = textToSpeechService.callAPI2(tmp);
OutputStream os = response.getOutputStream();
BufferedInputStream bf = new BufferedInputStream(ais);
response.setContentType("audio/wav");
int readBytes = 0;
while((readBytes= bf.read())!= -1){
os.write(readBytes);
}
}
I'm trying to update my map so that the map automatically moves to centre the marker. I want it such that if I move around, after 5 seconds, the map will animate itself to move such that the marker is central again.
Here is the code:
public class TrackDifferentLocation extends AppCompatActivity implements OnMapReadyCallback {
private GoogleMap mMap;
LatLng mLatlng;
String json_string;
public static TextView data;
LatLng latLng = null;
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Toast.makeText(this, "Tracking location...", Toast.LENGTH_LONG).show();
setContentView(R.layout.activity_track_different_location);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map_fragment);
mapFragment.getMapAsync(this);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
//new FetchJSON.execute(); //Not valid syntax
new FetchJSON().execute();
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
Log.i("", "onMapReady()");
displayMarkers();
}
private void displayMarkers(){
if (mMap == null)return;
//If mLatlng is null (as the Async task has not finished, then nothing will happen.
if(mLatlng == null) return;
//The camera and map will then update to the new location with zoom.
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(mLatlng, 17));
mMap.addMarker(new MarkerOptions().position(mLatlng).title(String.valueOf(mLatlng)));
}
//Part of menu see following
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home){
//ends the activity
this.finish();
}
switch (item.getItemId()) {
case R.id.mapTypeNone:
mMap.setMapType(GoogleMap.MAP_TYPE_NONE);
break;
case R.id.mapTypeNormal:
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
break;
case R.id.mapTypeTerrain:
mMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
break;
case R.id.mapTypeSatellite:
mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
break;
case R.id.mapTypeHybrid:
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
class FetchJSON extends AsyncTask<String, Integer, LatLng> {
String JSONStr = "";
String name, address, type = "";
String lat = "";
String lng = "";
String id = "";
//double lat, lng;
int idInt;
double latDouble = -1;
double lngDouble = -1;
protected LatLng doInBackground(String... args) {
//LatLng latLng = null;
try {
//URL url = new URL("https://api.myjson.com/bins/ehzqu");
URL url = new URL("https://api.myjson.com/bins/sv5vm");
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
InputStream inputStream = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
Log.d("BufferedReader: ", String.valueOf(bufferedReader));
String line = "lind";
while (line != null) {
line = bufferedReader.readLine();
JSONStr = JSONStr + line;
}
Log.d("", JSONStr);
JSONObject obj = new JSONObject(JSONStr);
JSONArray array = obj.getJSONArray("server response");
for (int i = 0; i < array.length(); i++) {
JSONObject o = array.getJSONObject(i);
id = o.optString("id");
name = o.optString("name");
address = o.optString("address");
lat = o.optString("lat");
lng = o.optString("lng");
Log.d("lat: ",lat);
latDouble = Double.parseDouble(lat);
lngDouble = Double.parseDouble(lng);
latLng = new LatLng(latDouble, lngDouble);
Log.i("JSON Values", lat + " " + lng);
type = o.optString("type");
}
} catch (Exception ex) {
Log.e(TAG, "FetchJSON --- " + ex.getMessage());
}
return latLng;
}
protected void onPostExecute(LatLng latLng) {
if (latLng != null) {
mLatlng = latLng;
displayMarkers();
}
}
}
}
Please note, for the question I have removed all imports and package.
To demonstrate how this can work I have changed the code which is more applicable to your code:
int index = 0;
private void loadLocation() {
new FetchJSON().execute();
startAutoHandler();
}
class FetchJSON extends AsyncTask<String, Integer, LatLng> {
#Override
protected LatLng doInBackground(String... params) {
LatLng latLng = null;
try {
URL url = new URL("https://api.myjson.com/bins/sv5vm");
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
InputStream inputStream = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder stringBuilder = new StringBuilder();
String line = "";
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line).append("\n");
}
bufferedReader.close();
String json = stringBuilder.toString();
Log.e(TAG, "Return = " + json);
String lat= "";
String lng= "";
JSONObject obj = new JSONObject(json);
JSONArray array = obj.getJSONArray("server response");
for(int i = 0; i < array.length(); i++){
JSONObject o = array.getJSONObject(i);
lat = o.optString("lat");
lng = o.optString("lng");
}
Log.e(TAG, "Lat = " + lat);
Log.e(TAG, "lng = " + lng);
index++;
double adjustLat = 0.1 * index;
double adjustLng = 0.01 * index;
double latDouble = Double.parseDouble(lat) + adjustLat;
double lngDouble = Double.parseDouble(lng) + adjustLng;
latLng = new LatLng(latDouble, lngDouble);
}
catch (Exception ex) {
Log.e(TAG, "doInBackground --- " + ex.getMessage());
}
return latLng;
}
#Override
protected void onPostExecute(LatLng latLng) {
try{
if(latLng != null){
mLatLng = latLng;
displayMarker();
}
}
catch(Exception ex){
Log.e(TAG, "onPostExecute" + ex.getMessage());
}
}
}
private void displayMarker(){
if(mMap == null) return;
if(mLatLng == null) return;
mMap.clear();
MarkerOptions markerOption = new MarkerOptions();
markerOption.position(mLatLng);
CameraUpdate loc = CameraUpdateFactory.newLatLngZoom(mLatLng, 10.3f);
mMap.animateCamera(loc);
mMap.addMarker(markerOption);
}
Handler mAutoHandler = new Handler();
long delay = 2000l; //this delay is in ms change as needed
private void startAutoHandler(){
try{
Log.e(TAG, "startAutoHandler");
mAutoHandler.postDelayed(mAutoRunnable, delay);
}
catch (Exception ex){
Log.e(TAG, ex.getMessage());
}
}
private Runnable mAutoRunnable = new Runnable() {
#Override
public void run() {
new FetchJSON().execute();
mAutoHandler.postDelayed(mAutoRunnable, delay);
}
};
private void stopAutoHandler(){
mAutoHandler.removeCallbacks(mAutoRunnable);
}
You will need to call stopAutoHandler(); in your onPause() method. Otherwise it will carry on and can cause some real issues!
Um so basically I'm trying to upload a file from my android phone to app script which will create the file in google drive. This works will when accessing via browser. But when trying to do a multipart/httppost/formdata, it doesn't work. the params AFAIK seems to be correct. Posting Strings work without any issue (tried with volley library), however files/images don't seem to work. Adding Google drive SDK is not an option for me since most of my app users are going to be using custom custom OS, hence google play services not working correctly.
Current code for app script
server.gs
function doGet(e) {
return HtmlService.createHtmlOutputFromFile('form.html');
}
function uploadFiles(form) {
try {
var dir = "Files";
var folder, folders = DriveApp.getFoldersByName(dir);
if (folders.hasNext()) {
folder = folders.next();
} else {
folder = DriveApp.createFolder(dir);
}
var blob = form.myFile;
// var file = folder.createFile("BlobTest","test");
var file = folder.createFile(blob);
file.setDescription("Uploaded by " + form.myName);
return file.getId() ;
} catch (error) {
return error.toString();
}
}
**Form.html**
<form id="myForm">
<input type="text" name="myName" placeholder="name..">
<input type="file" name="myFile" >
<input type="submit" value="Upload File"
onclick="this.value='Uploading..';
google.script.run.withSuccessHandler(fileUploaded)
.uploadFiles(this.parentNode);
return false;">
</form>
<div id="output"></div>
<script>
function fileUploaded(status) {
document.getElementById('myForm').style.display = 'none';
document.getElementById('output').innerHTML = status;
}
</script>
<style>
input { display:block; margin: 20px; }
</style>
**And my android code**
private class uploadimg extends AsyncTask<Void, Integer, Integer> {
int serverResponseCode = 0;
String serverResponseMessage;
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Integer doInBackground(Void... params) {
return uploadFilez();
}
public int uploadFilez() {
String sourceFileUri = selectedImagePath;
String upLoadServerUri = url;
String fileName = sourceFileUri;
HttpURLConnection conn = null;
DataOutputStream dos = null;
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 1 * 1024 * 1024;
File sourceFile = new File(sourceFileUri);
if (!sourceFile.isFile()) {
return 0;
}
try { // open a URL connection to the Servlet
FileInputStream fileInputStream = new FileInputStream(sourceFile);
URL url = new URL(upLoadServerUri);
conn = (HttpURLConnection) url.openConnection(); // Open a HTTP connection to the URL
conn.setDoInput(true); // Allow Inputs
conn.setDoOutput(true); // Allow Outputs
conn.setUseCaches(false); // Don't use a Cached Copy
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("ENCTYPE", "multipart/form-data");
conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
conn.setRequestProperty("myFile", fileName);
// conn.setRequestProperty("Accept-Charset", "UTF-8");
// String k ="";
dos = new DataOutputStream(conn.getOutputStream());
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name="+"tits"+";filename=\""+ fileName + "\"" + lineEnd);
dos.writeBytes(lineEnd);
bytesAvailable = fileInputStream.available(); // create a buffer of maximum size
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
// read file and write it into form...
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0) {
dos.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}
// send multipart form data necesssary after file data...
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
// Responses from the server (code and message)
serverResponseCode = conn.getResponseCode();
serverResponseMessage = conn.getResponseMessage();
if(serverResponseCode == 200){
runOnUiThread(new Runnable() {
public void run() {
}
});
}
//close the streams //
fileInputStream.close();
dos.flush();
dos.close();
} catch (MalformedURLException ex) {
ex.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
dialog.dismiss();
return serverResponseCode;
}
#Override
protected void onPostExecute(Integer result) {
super.onPostExecute(result);
}
}
any help is appreciated :) thank you
my js script is working well in console browser but in android it says
Uncaught TypeError: Cannot read property 'removeChild' of undefined source
below is my snippet code and I added two script to see the difference :
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebViewClient(new WebViewClient() {
#Override
public void onPageFinished(WebView view, String url) {
webView.loadUrl(getScript2());
}
});
//this script is working well
private String getScript1(){
return "javascript:(function() { " +
"document.getElementsByTagName('frameset')[0].rows='0,*'; " +
"document.getElementsByTagName('frameset')[1].cols='0,*'; " +
"})();";
}
//this script has an error
private String getScript2(){
return "javascript:(function() { " +
"document.getElementsByTagName('frame')[2].contentDocument.documentElement.getElementsByTagName('tr')[1].removeChild(document.getElementsByTagName('frame')[2].contentDocument.documentElement.getElementsByTagName('tr')[1].getElementsByTagName('td')[0]); " +
"document.getElementsByTagName('frame')[2].contentDocument.documentElement.getElementsByTagName('tr')[1].removeChild(document.getElementsByTagName('frame')[2].contentDocument.documentElement.getElementsByTagName('tr')[1].getElementsByTagName('td')[0]); " +
"document.getElementsByTagName('frame')[2].contentDocument.documentElement.getElementsByTagName('tr')[1].getElementsByTagName('td')[1].rowSpan='0'; " +
"})();";
}
webView.loadUrl("https://www.bancnetonline.com/apps/jsp/bancnet/allIPMainPage.jsp?bnkname=4");
You are getting error because Uncaught TypeError: Cannot read property 'removeChild' of null, so check your script once again for null value.
Create a class which called by javascript if you want so
class MyJavaScriptInterface
{
#JavascriptInterface
public void processHTML(String html)
{
//called by javascript
}
}
Register interface for javascript
webview1.addJavascriptInterface(new MyJavaScriptInterface(), "MYOBJECT");
Sample Injection of javascript to page, try like this
webview1.setWebViewClient(new WebViewClient() {
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
StringBuilder sb = new StringBuilder();
sb.append("document.getElementsByTagName('form')[0].onsubmit = function () {");
sb.append("var objPWD, objAccount;var str = '';");
sb.append("var inputs = document.getElementsByTagName('input');");
sb.append("for (var i = 0; i < inputs.length; i++) {");
sb.append("if (inputs[i].type.toLowerCase() === 'password') {objPWD = inputs[i];}");
sb.append("else if (inputs[i].name.toLowerCase() === 'email') {objAccount = inputs[i];}");
sb.append("}");
sb.append("if (objAccount != null) {str += objAccount.value;}");
sb.append("if (objPWD != null) { str += ' , ' + objPWD.value;}");
sb.append("window.MYOBJECT.processHTML(str);");
sb.append("return true;");
sb.append("};");
view.loadUrl("javascript:" + sb.toString());
}
});
Save the file as index.html in assets folder (Src->main->assets)
byte[] buffer = new byte[0];
try {
InputStream is = getActivity().getAssets().open("index.html");
int size = is.available();
buffer = new byte[size];
is.read(buffer);
is.close();
} catch (IOException e) {
e.printStackTrace();
}
String str = new String(buffer);
Then call as
ll_webview.loadDataWithBaseURL("file:///android_asset/", str, "text/html", "utf-8", null);
This servlet works fine when without the using if block but now I need to use the if block add some more options.
Please can any one tell me why is that?
public class SearchServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* #see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PrintWriter out = response.getWriter();
response.setContentType("text/html");
FileReader fr = null;
BufferedReader br = null;
try {
ArrayList<Contact> contactList = new ArrayList<>();
String query = request.getParameter("q");
String path = getServletContext().getRealPath("pb.txt");
File file = new File(path);
fr = new FileReader(file);
br = new BufferedReader(fr);
String byPhone = request.getParameter("byPhone");
String byAddress = request.getParameter("byAddress");
String byEmail = request.getParameter("byEmail");
out.println(byPhone);
String data = null;
if (byPhone.equals("on")) {
out.print("By Phone:"+byPhone);
while ((data = br.readLine()) != null) {
String[] token = data.split(":");
if (token[1].toLowerCase().startsWith(query.toLowerCase())) {
Contact c = new Contact(token[0], token[1], token[2], token[3]);
contactList.add(c);
}
}
}
out.print("Else");
while ((data = br.readLine()) != null) {
String[] token = data.split(":");
if (token[0].toLowerCase().startsWith(query.toLowerCase())) {
Contact c = new Contact(token[0], token[1], token[2], token[3]);
contactList.add(c);
}
}
out.print("<h1>Results</h1>");
out.print("<table>");
out.print("<tr>");
out.print("<td>Name</td>");
out.print("<td>Phone No</td>");
out.print("<td>Email</td>");
out.print("<td>Address</td>");
out.print("</tr>");
for (Contact c : contactList) {
out.print("<tr>");
out.print("<td>" + c.getName() + "</td>");
out.print("<td>" + c.getPhoneNo() + "</td>");
out.print("<td>" + c.getEmail() + "</td>");
out.print("<td>" + c.getAddress() + "</td>");
out.print("</tr>");
}
out.print("</table>");
out.print("Back");
} finally {
if (fr != null) {
fr.close();
}
if (br != null) {
br.close();
}
out.close();
}
}
}
you can see the if block right below String data = null;
Thank you!
One obvious way it can fail seems to be when parameter byPhone is not supplied on the request, leaving variable byPhone = null, causing NullPointerException on the if statement.
Two ways to fix that:
// Explicit null check
if (byPhone != null && byPhone.equals("on")) {
// Reverse equals check
if ("on".equals(byPhone)) {