i want to connect odbc connection to my android application. my database is oracle 10g. Here in my code my table name is world. After compiling my program and close the emulator open table in oracle database the values could not be stored
The same coding i compiled normal javac compiler in cmp prompt the values should be stored, if i compiling in android application in eclipse ide the values could not be stored.Pls give one solution or any changes in my code
Thanks in advance
package com.odbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import android.app.Activity;
import android.os.Bundle;
import android.R.id;
public class OdbcActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try
{
String country="india";
String city="delhi";
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection con=DriverManager.getConnection("jdbc:odbc:world","system","love");
PreparedStatement ps=con.prepareStatement("insert into world(country,city) values(?,?)");
ps.setString(1,country);
ps.setString(2,city);
ps.executeUpdate();
}
catch(Exception e)
{
System.out.println("Exception:"+e);
}
}
}
Android apps connecting directly to a DMBS isn't an architecture I'd recommend. Instead, I suggest setting an application on the server (using Java, Rails, whatever) that reads the database and exposes a simple HTTP web service for the Android app to get at the data. Not only is that a more sound architecture, I'm not even sure you can run JDBC drivers in an Android device. Using my architecture, you isolate the device from the structure and type of your database.
Related
I'm trying to build an NFC card emulator in kivy (similar to https://github.com/okanatas/NFCCardEmulator).
I can't simply subclass HostApduService (i.e.)
from jnius import autoclass
HostApduService=autoclass(android.nfc.cardemulation.HostApduService)
class NfcService(HostApduService):
def processCommandApdu(self, commandApdu, extras):
# Process the incoming APDU command
# and return a response APDU
# Example: Respond with the same data as received
return self.getBytes(commandApdu)
so instead I've tried to include some java files (similar to to the ones in the github) i.e.
package nfccardemulator;
import android.nfc.cardemulation.HostApduService;
import android.os.Bundle;
public class HostCardEmulatorService extends HostApduService {
#Override
public byte[] processCommandApdu(byte[] commandApdu, Bundle extras) {
...
}
}
and some other utilities files in Java.
I've put them in the services/nfccardemulator folder and added the following to buildozer:
android.add_src = services
I've checked the apk, and the classes are compiled and present. But I'm struggling to access them via autoclass
If I say
HostCardEmulatorService = autoclass("nfccardemulator.HostCardEmulatorService")
I get an error instantiating it.
I'm not sure if I'm even setting up a Service like this correctly.
I've seen an example of PythonService i.e.
PythonService = autoclass('org.kivy.android.PythonService')
and then having to use multiprocessing on the service while the kivy process runs separately.
Is what I'm trying to do even possible currently?
Thanks
I need to implement SSL Certificate Pinning in my react native application.
I know very little about SSL/TLS let alone pinning.
I am also not a native mobile developer, though I know Java and learned Objective-C on this project enough to get around.
I started searching for how to execute this task.
Doesn't React Native already implement this?
No, My initial search lead me to this proposal which has received no activity since August 2nd 2016.
From it I learned that react-native uses OkHttp which does support Pinning, but I wouldn't be able to pull it off from Javascript, which is not really a requirement but a plus.
Implement it in Javascript.
While react seems like it uses the nodejs runtime, it is more like a browser than node, meaning it does not support all native modules, specifically the https module, for which I had implemented certificate pinning following this article. Thus could not carry it into react native.
I tried using rn-nodeify but the modules didn't work. This has been true since RN 0.33 to RN 0.35 which I'm currently on.
Implement using phonegap plugin
I thought of using a phongape-plugin however since I have a dependency on libraries that require react 0.32+ I can't use react-native-cordova-plugin
Just do it natively
While I'm not a native app developer I can always take a crack at it, only a matter of time.
Android has certificate pinning
I learned that android supports SSL Pinning however was unsuccessful as it seems that this approach does not work Prior to Android 7. As well as only working for android.
The bottom line
I have exhausted several directions and will continue to pursue more native implementation, maybe figure out how to configure OkHttp and RNNetworking then maybe bridging back to react-native.
But is there already any implementations or guide for IOS and android?
After exhausting the current spectrum of available options from Javascript I decided to simply implement certificate pinning natively it all seems so simple now that I'm done.
Skip to headers titled Android Solution and IOS Solution if you don't want to read through the process of reaching the solution.
Android
Following Kudo's recommendation I thought out to implement pinning using okhttp3.
client = new OkHttpClient.Builder()
.certificatePinner(new CertificatePinner.Builder()
.add("publicobject.com", "sha1/DmxUShsZuNiqPQsX2Oi9uv2sCnw=")
.add("publicobject.com", "sha1/SXxoaOSEzPC6BgGmxAt/EAcsajw=")
.add("publicobject.com", "sha1/blhOM3W9V/bVQhsWAcLYwPU6n24=")
.add("publicobject.com", "sha1/T5x9IXmcrQ7YuQxXnxoCmeeQ84c=")
.build())
.build();
I first started by learning how to create a native android bridge with react nativecreating a toast module. I then extended it with a method for sending a simple request
#ReactMethod
public void showURL(String url, int duration) {
try {
Request request = new Request.Builder()
.url(url)
.build();
Response response = client.newCall(request).execute();
Toast.makeText(getReactApplicationContext(), response.body().string(), duration).show();
} catch (IOException e) {
Toast.makeText(getReactApplicationContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
Succeeding in sending a request I then turned to sending a request pinned.
I used these packages in my file
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.CertificatePinner;
import java.io.IOException;
import java.util.Map;
import java.util.HashMap;
Kudo's approach wasn't clear on where I would get the public keys or how to generate them. luckily okhttp3 docs in addition to providing a clear demonstration of how to use the CertificatePinner stated that to get the public keys all I would need to do is send a request with an incorrect pin, and the correct pins will appear in the error message.
After taking a moment to realise that OkHttpClent.Builder() can be chained and I can include the CertificatePinner before the build, unlike the misleading example in Kudo's proposal (probably and older version) I came up with this method.
#ReactMethod
public void getKeyChainForHost(String hostname, Callback errorCallbackContainingCorrectKeys,
Callback successCallback) {
try {
CertificatePinner certificatePinner = new CertificatePinner.Builder()
.add(hostname, "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAA=")
.build();
OkHttpClient client = (new OkHttpClient.Builder()).certificatePinner(certificatePinner).build();
Request request = new Request.Builder()
.url("https://" + hostname)
.build();
Response response =client.newCall(request).execute();
successCallback.invoke(response.body().string());
} catch (Exception e) {
errorCallbackContainingCorrectKeys.invoke(e.getMessage());
}
}
Then replacing the public keychains I got in the error yielded back the page's body, indicating I had made a successful request, I change one letter of the key to make sure it was working and I knew I was on track.
I finally had this method in my ToastModule.java file
#ReactMethod
public void getKeyChainForHost(String hostname, Callback errorCallbackContainingCorrectKeys,
Callback successCallback) {
try {
CertificatePinner certificatePinner = new CertificatePinner.Builder()
.add(hostname, "sha256/+Jg+cke8HLJNzDJB4qc1Aus14rNb6o+N3IrsZgZKXNQ=")
.add(hostname, "sha256/aR6DUqN8qK4HQGhBpcDLVnkRAvOHH1behpQUU1Xl7fE=")
.add(hostname, "sha256/HXXQgxueCIU5TTLHob/bPbwcKOKw6DkfsTWYHbxbqTY=")
.build();
OkHttpClient client = (new OkHttpClient.Builder()).certificatePinner(certificatePinner).build();
Request request = new Request.Builder()
.url("https://" + hostname)
.build();
Response response =client.newCall(request).execute();
successCallback.invoke(response.body().string());
} catch (Exception e) {
errorCallbackContainingCorrectKeys.invoke(e.getMessage());
}
}
Android Solution Extending React Native's OkHttpClient
Having figured out how to send pinned http request was good, now I can use the method I created, but ideally I thought it would be best to extend the existing client, so as to immediately gain the benefit of implementing.
This solution is valid as of RN0.35 and I don't know how it will fair in the future.
While looking into ways of extending the OkHttpClient for RN I came across this article explaining how to add TLS 1.2 support through replacing the SSLSocketFactory.
reading it I learned react uses an OkHttpClientProvider for creating the OkHttpClient instance used by the XMLHttpRequest Object and therefore if we replace that instance we would apply pinning to all the app.
I added a file called OkHttpCertPin.java to my android/app/src/main/java/com/dreidev folder
package com.dreidev;
import android.util.Log;
import com.facebook.react.modules.network.OkHttpClientProvider;
import com.facebook.react.modules.network.ReactCookieJarContainer;
import java.util.concurrent.TimeUnit;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.CertificatePinner;
public class OkHttpCertPin {
private static String hostname = "*.efghermes.com";
private static final String TAG = "OkHttpCertPin";
public static OkHttpClient extend(OkHttpClient currentClient){
try {
CertificatePinner certificatePinner = new CertificatePinner.Builder()
.add(hostname, "sha256/+Jg+cke8HLJNzDJB4qc1Aus14rNb6o+N3IrsZgZKXNQ=")
.add(hostname, "sha256/aR6DUqN8qK4HQGhBpcDLVnkRAvOHH1behpQUU1Xl7fE=")
.add(hostname, "sha256/HXXQgxueCIU5TTLHob/bPbwcKOKw6DkfsTWYHbxbqTY=")
.build();
Log.d(TAG, "extending client");
return currentClient.newBuilder().certificatePinner(certificatePinner).build();
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
return currentClient;
}
}
This package has a method extend which takes an existing OkHttpClient and rebuilds it adding the certificatePinner and returns the newly built instance.
I then modified my MainActivity.java file following this answer's advice by adding the following methods
.
.
.
import com.facebook.react.ReactActivity;
import android.os.Bundle;
import com.dreidev.OkHttpCertPin;
import com.facebook.react.modules.network.OkHttpClientProvider;
import okhttp3.OkHttpClient;
public class MainActivity extends ReactActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
rebuildOkHtttp();
}
private void rebuildOkHtttp() {
OkHttpClient currentClient = OkHttpClientProvider.getOkHttpClient();
OkHttpClient replacementClient = OkHttpCertPin.extend(currentClient);
OkHttpClientProvider.replaceOkHttpClient(replacementClient);
}
.
.
.
This solution was carried out in favor of completely reimplementing the OkHttpClientProvider createClient method, as inspecting the provider I realized that the master version had implemented TLS 1.2 support but was not yet an available option for me to use, and so rebuilding was found to be the best means of extending the client. I'm wondering how this approach will fair as I upgrade but for now it works well.
Update It seems that starting 0.43 this trick no longer works. For timebound reasons I will freeze my project at 0.42 for now, until the reason for why rebuilding stopped working is clear.
Solution IOS
For IOS I had thought I would need to follow a similar method, again starting with Kudo's proposal as my lead.
Inspecting the RCTNetwork module I learned that NSURLConnection was used, so instead of trying to create a completely new module with AFNetworking as suggested in the proposal I discovered TrustKit
following its Getting Started Guide I simply added
pod 'TrustKit'
to my podfile and ran pod install
the GettingStartedGuide explained how I can configure this pod from my pList.file but preferring to use code than configuration files I added the following lines to my AppDelegate.m file
.
.
.
#import <TrustKit/TrustKit.h>
.
.
.
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Initialize TrustKit
NSDictionary *trustKitConfig =
#{
// Auto-swizzle NSURLSession delegates to add pinning validation
kTSKSwizzleNetworkDelegates: #YES,
kTSKPinnedDomains: #{
// Pin invalid SPKI hashes to *.yahoo.com to demonstrate pinning failures
#"efghermes.com" : #{
kTSKEnforcePinning:#YES,
kTSKIncludeSubdomains:#YES,
kTSKPublicKeyAlgorithms : #[kTSKAlgorithmRsa2048],
// Wrong SPKI hashes to demonstrate pinning failure
kTSKPublicKeyHashes : #[
#"+Jg+cke8HLJNzDJB4qc1Aus14rNb6o+N3IrsZgZKXNQ=",
#"aR6DUqN8qK4HQGhBpcDLVnkRAvOHH1behpQUU1Xl7fE=",
#"HXXQgxueCIU5TTLHob/bPbwcKOKw6DkfsTWYHbxbqTY="
],
// Send reports for pinning failures
// Email info#datatheorem.com if you need a free dashboard to see your App's reports
kTSKReportUris: #[#"https://overmind.datatheorem.com/trustkit/report"]
},
}
};
[TrustKit initializeWithConfiguration:trustKitConfig];
.
.
.
I got the public key hashes from my android implementation and it just worked (the version of TrustKit I received in my pods is 1.3.2)
I was glad IOS turned out to be a breath
As a side note TrustKit warned that it's Auto-swizzle won't work if the NSURLSession and Connection are already swizzled. that said it seems to be working well so far.
Conclusion
This answer presents the solution for both Android and IOS, given I was able to implement this in native code.
One possible improvement may be to implement a common platform module where setting public keys and configuring the Network providers of both android and IOS can be managed in javascript.
Kudo's proposal mentioned simply adding the public keys to the js bundle may however expose a vulnerability, where somehow the bundle file can be replaced.
I don't know how that attack vector can function, but certainly the extra step of signing the bundle.js as proposed may protect the js bundle.
Another approach may be to simply encode the js bundle into a 64 bit string and include it in the native code directly as mentioned in this issue's conversation. This approach has the benefit of obfuscating as well hardwiring the js bundle into the app, making it inaccessible for attackers or so I think.
If you read this far I hope I enlightened you on your quest for fixing your bug and wish you enjoy a sunny day.
You can use this lib https://github.com/nlt2390/react-native-pinning-ssl
It verifies SSL connection using SHA1 keys, not certificates.
Placing sqlite-jdbc-3.7.2.jar in the libs folder causes eclipse to run into a heap error. Placing it in a separate folder and adding it to the build path causes class not found errors.
Adding it to the exported jars list causes the heap error as well.
Any ideas?
Quick answer, it'll fail no matter where you place it. The problem is that some native jar libraries are just not supported by Android. We may have to depend on some developers to port some better resolutions.
In this case (while I'm sure there are others) you can use, instead SQLDroid.jar. I have tested it and so far it performs just as the normal sqlite-jdbc-3.7.2.jar does in native java programs.
I'm sure (as I mentioned in my comment to cYrixmorten, the purpose of choosing to use a native sqlite support is to have portability for your other sqlite databases, as well as having the native CRUD support.
A tested working example using SQLDroid.jar:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
Code Segment:
public void checksqlite()
{
try {
String db = "jdbc:sqlite:" + getFilesDir() + "/test.db";
Class.forName("org.sqldroid.SQLDroidDriver");
Connection conn = DriverManager.getConnection(db);
Statement stat = conn.createStatement();
stat.executeUpdate("create table primes (number int);");
stat.executeUpdate("insert into primes values (2);");
stat.executeUpdate("insert into primes values (3);");
stat.executeUpdate("insert into primes values (5);");
stat.executeUpdate("insert into primes values (7);");
ResultSet rs = stat.executeQuery("select * from primes");
boolean b = rs.first();
while (b) {
Log.d("JDBC", "Prime=" + rs.getInt(1));
b = rs.next();
}
conn.close();
} catch (Exception e) {
Log.e("JDBC", "Error", e);
}
}
The links and comments provided by cYrixmorten was invaluable in helping me to find this resolution. I hope others can benefit from it.
I followed the tutorial below.
https://developers.google.com/eclipse/docs/running_and_debugging_2_0
which basically added a GAE backend to my existing app. I then try out the example below, run it on the local development server and I get the exception below which occurs after
Note result = endpoint.insertNote(note).execute();
is called.
com.google.api.client.googleapis.json.GoogleJsonResponseException: 404 Not Found
My code is below.
package com.cloudnotes;
import java.io.IOException;
import java.util.Date;
import android.os.AsyncTask;
import android.content.Context;
import com.cloudnotes.noteendpoint.Noteendpoint;
import com.cloudnotes.noteendpoint.model.Note;
import com.google.api.client.extensions.android.http.AndroidHttp;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.json.jackson.JacksonFactory;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new EndpointsTask().execute(getApplicationContext());
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
public class EndpointsTask extends AsyncTask<Context, Integer, Long> {
protected Long doInBackground(Context... contexts) {
Noteendpoint.Builder endpointBuilder = new Noteendpoint.Builder(
AndroidHttp.newCompatibleTransport(),
new JacksonFactory(),
new HttpRequestInitializer() {
public void initialize(HttpRequest httpRequest) { }
});
Noteendpoint endpoint = CloudEndpointUtils.updateBuilder(
endpointBuilder).build();
try {
Note note = new Note().setDescription("Note Description");
String noteID = new Date().toString();
note.setId(noteID);
note.setEmailAddress("E-Mail Address");
Note result = endpoint.insertNote(note).execute();
} catch (IOException e) {
e.printStackTrace();
}
return (long) 0;
}
}
}
Another possible cause for this problem is not setting the correct applicationId in appengine-web.xml:
<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<application>APPLICATION_ID_HERE</application>
...
</appengine-web-app>
Another possible reason for 404 if you call the method with a null parameter and the method does not accept null parameters.
I had a similar issue with a method with 4 String parameters and I sent null for one of them and all I got was a stupid 404.
Another possible reason for 404 on the development(local) server is that you have a parameter with some strange characters (like a url for example) that the development(local) server does not handle correctly event if it works fine on the app engine live servers. Possible solution: instead of multiple params use a simple java object.
I had the same problem and this is how I fixed it.
A little background
I had two versions of the API deployed to App Engine which I believe it should be OK. The admin console didn't show any problem and I was getting the 200 OK code after deploying version 2 of the API in log file.
/_ah/spi/BackendService.getApiConfigs 200 118ms 8kb
but no matter what I tried I was always getting the 404 Not Found error.
I am not sure what the problem was but I think Web Server at App Engine was redirecting all the requests to the version 1. It could be because both versions had the following settings in their web.xml.
<servlet-mapping>
<servlet-name>SystemServiceServlet</servlet-name>
<url-pattern>/_ah/spi/*</url-pattern>
</servlet-mapping>
Solution
I removed version 1 and redeployed version 2. Then everything just worked fine.
This comes down to the app engine default version being different from the one you've deployed. Go here:
https://appengine.google.com/deployment?app_id=s~your-project-id
and change your default version
this happen because your deploy back-end is not fully deployed. just re-deploy your back-end and make sure you got the message deploy succeed. you can check the detail deploy process on the top page header. also, you can test by visiting the url to check:
https://developers.google.com/apis-explorer/?base=https://[YOUR_PROJECT_ID].appspot.com/_ah/api#p/
Try to update your plugin and dependency libraries to the latest version. See https://stackoverflow.com/a/37639701/857346.
In build gradle do:
minifyEnabled false
I have the following project structure.
My StockInfo.java is perfectly fine.
StockInfo.java (No error)
package org.yccheok.jstock.engine;
import android.os.Parcel;
import android.os.Parcelable;
public class StockInfo implements Parcelable {
...
...
StockInfo.aidl (No error)
package org.yccheok.jstock.engine;
parcelable StockInfo;
StockInfoObserver.aidl (Error!)
package org.yccheok.jstock.engine;
interface StockInfoObserver {
void update(StockInfo stockInfo);
}
AutoCompleteApi.aidl (Error!)
package org.yccheok.jstock.engine;
interface AutoCompleteApi {
void handle(String string);
void attachStockInfoObserver(StockInfoObserver stockInfoObserver);
}
However, Eclipse complains in StockInfoObserver.aidl (It does complain AutoCompleteApi.aidl too, as it cannot process StockInfoObserver.aidl),
parameter stockInfo (1) unknown type StockInfo
I tried for an hour, but still not able to find out, why in aidl, StockInfo is not being recognized although I had
Provided StockInfo.aidl
Provided StockInfo.java
Any idea?
Here are the complete errors.
Note, AutoCompleteApi.aidl is very much dependent on StockInfoObserver.aidl. That's why you will see the error.
I share the entire project for your reference purpose : https://www.dropbox.com/s/0k5pe75jolv5mtq/jstock-android.zip
According to Android documentation You must include an import statement for each additional type not listed above, even if they are defined in the same package as your interface
Try to add this line to StockInfoObserver.aidl
import org.yccheok.jstock.engine.StockInfo;