MyContentProvider.onCreate() is not being called? - java

The onCreate of my userDatabase that extends ContentProvider is not properly called
Here is some of my userBatabase code:
public class userDatabase extends ContentProvider {
private MainDatabaseHelper mOpenHelper;
public userDatabase(){}
public static final class MainDatabaseHelper extends SQLiteOpenHelper{...}
#Override
public boolean onCreate() {
mOpenHelper = new MainDatabaseHelper(getContext());
return true;
}
#Override
public Uri insert(Uri uri, ContentValues values) {
long id = mOpenHelper.getWritableDatabase().insert("Users", null, values);
return Uri.withAppendedPath(CONTENT_URI, "" + id);
}
...
}
In my main activity I call:
userDatabase cpDatabase = new userDatabase();
But when I try to call cpDatabase.insert(userDatabase.CONTENT_URI, values);
Everything crashes inside insert when mOpenHelper.getWritableDatabase().insert("Users", null, values); is called.
I found out that mOpenHelper.getWritableDatabase() was the issue, as it wont run even by itself, and then I found out this was because mOpenHelper was null.
I instantiate mOpenHelper in the constructor, so I figure its not running. A few log messages confirm this, when I call userDatabase cpDatabase = new userDatabase(); my log messages showed that the userDatabase() constructor ran normally, but the onCreate never ran, so the mOpenHelper never got instantiated.
(Note: with these log messages, I noticed that the constructor and the onCreate for my userDatabase got called when my app started. I have no idea why or where. I dont understand why this was run before i tried to create an instance. and even though it was run, mOpenHelper still wasn't initialized, and when i created an instance, the constructor ran but the onCreate didnt.)
What could possibly be happening, and how can I make my onCreate run?

Since you are using content providers, according to the documentation
This method is called for all registered content providers on the
application main thread at application launch time
And the way you try to use the content provider is seems wrong and,
You don't need to manually instantiate the content provider, once you made the request via the ContentResolver by passing the URI, the system inspects the authority of the given URI and passes the request to the content provider registered with the authority.
for example
getContentResolver().delete(uri, null, null);
Where the uri is, the full URI to query.
This tutorial will guide you in right direction

Related

How can I DetectFaces in Amazon Rekognition AWS with Android Studio?

I have tried so many way but i can't succeed. I haven't found any source code examples for Android(about rekognition)
there's a source code in JAVA in the Developer Guide but i cannot implement that even though I tried TT
I try to detect faces by sending an image file from an external storage(from the emulator)
I don't know what i did wrong(I'm not good at coding)
Here is my code
AmazonRekognitionClient amazonRekognitionClient;
Image getAmazonRekognitionImage;
DetectFacesRequest detectFaceRequest;
DetectFacesResult detectFaceResult;
File file = new File(Environment.getExternalStorageDirectory(),"sungyeol.jpg.jpg");
public void test_00(View view) {
ByteBuffer imageBytes;
try{
InputStream inputStream = new FileInputStream(file.getAbsolutePath().toString());
imageBytes = ByteBuffer.wrap(IOUtils.toByteArray(inputStream));
Log.e("InputStream: ",""+inputStream);
Log.e("imageBytes: ","");
getAmazonRekognitionImage.withBytes(imageBytes);
// Initialize the Amazon Cognito credentials provider
CognitoCachingCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider(
getApplicationContext(),
"us-east-2:.......", // Identity Pool ID
Regions.US_EAST_2 // Region
);
//I want "ALL" attributes
amazonRekognitionClient = new AmazonRekognitionClient(credentialsProvider);
detectFaceRequest = new DetectFacesRequest()
.withAttributes(Attribute.ALL.toString())
.withImage(getAmazonRekognitionImage);
detectFaceResult = amazonRekognitionClient.detectFaces(detectFaceRequest);
detectFaceResult.getFaceDetails();
}
catch(Exception ex){
Log.e("Error on something:","Message:"+ex.getMessage());
}
and here is my errors
02-04 09:30:07.268 29405-29405/? E/InputStream:: java.io.FileInputStream#a9b23e7
02-04 09:30:07.271 29405-29405/? E/Error on something:: Message:Attempt to invoke virtual method 'com.amazonaws.services.rekognition.model.Image com.amazonaws.services.rekognition.model.Image.withBytes(java.nio.ByteBuffer)' on a null object reference
what is a null object reference?
i try to change the file path but he said no such file ... and when I change to this path, there's errors above.
by the way I've already asked a user for a permission to access a folder from Emulator in Android
please help me
PS. sorry for my bad English
Thank you in advance.
Now I am ok with the issues. I have been through many many things <3 <3 <3.
Thank you
I'm Thai and I had to try harder to find the solutions because there's lack of information in the particular language. Here are my solutions.
My solutions are:
0.There is an endpoint for setting for the Rekognition-->
http://docs.aws.amazon.com/general/latest/gr/rande.html#rekognition_region
1.On a "null object reference issue" I found that I have to create a new object first such as "Image image = new Image();" <-- The "new" command creates an object instance in that class
2.After the above error, there are more errors (Errors on NetworkOnMainThreadException), so I tried everything until I found this page -->
https://docs.aws.amazon.com/cognito/latest/developerguide/getting-credentials.html the page said that ...
Consequently, I looked up for more information about the AsyncTask and after that I created an AsyncTask class and then I move all my code about the initialize, the request, the response to the AsyncTask class. ตอนรันตอนท้ายๆน้ำตาจิไหล my code worked... TT and by the conclusion the sungyeol.jpg.jpg file worked
for example
private void testTask(){
.... all code in the main thread particularly on the requests and responses
from the services
//print the response or the result
//Log.e() makes the message in the android monitor red like an error
Log.e("Response:", [responseparameter.toString()]);
}
//create the inherited class from the AsyncTask Class
//(you can create within your activity class)
class AsyncTaskRunner extends AsyncTask<String,String,String>{
#Override
public String doInBackground(String ... input){
testTask(); // call the testTask() method that i have created
return null; // this override method must return String
}
}
//I've created a button for running the task
public void buttonTask(View view){
AsyncTaskRunner runner = new AsyncTaskRunner();
runner.execute();
}
for more information about the AsyncTask:
https://developer.android.com/training/basics/network-ops/connecting.html#AsyncTask
http://www.compiletimeerror.com/2013/01/why-and-how-to-use-asynctask.html#.WJdkqVOLTIU
I hope these help :)

Executing thread only in one Android Activity

I have three java files in my Android project. Two are activities (MainActivity and GeoActivity) and one is a plain java file (PostHttp -> sends data to server via the HTTP POST)
I switch over to GeoActivity via a simple button on-click method. GeoActivity returns the co-ordinates of the current location in a TextView AND sends them to a remote server via the HTTP POST.
I have a Handler.class which executes sends the Post Message after a delay of 50s. Something like this below. The problem i have is that when i click the back button and switch over to MainActivity i can still see in LogCat the echoes receiving from the server that the data is still being sent. How can i stop that?
GeoActivity.class
public class GeoActivity extends Activity {
Location location;
private Handler mHandler = new Handler();
protected void onCreate(Bundle savedInstanceState) {
....
if(location != null){
mHandler.postDelayed(updateTask,0);
}
...
}
...
public Runnable updateTask = new Runnable(){
public void run(){
mlocListener.onLocationChanged(location);
//send coordinates with a delay of 50s
new PostHttp(getUDID(),latitude,longitude).execute();
mHandler.postDelayed(updateTask, 50000);
}
Try acting on the activity's life cycle.
For example:
#Override
protected void onStop() {
super.onStop(); // Always call the superclass method first
// Save the note's current draft, because the activity is stopping
// and we want to be sure the current note progress isn't lost.
ContentValues values = new ContentValues();
values.put(NotePad.Notes.COLUMN_NAME_NOTE, getCurrentNoteText());
values.put(NotePad.Notes.COLUMN_NAME_TITLE, getCurrentNoteTitle());
getContentResolver().update(
mUri, // The URI for the note to update.
values, // The map of column names and new values to apply to them.
null, // No SELECT criteria are used.
null // No WHERE columns are used.
);
}
This doesn't destroy the activity, it will reside in memory. However, you can always resume when needed.
Source:
Stopping and Restarting Android Activities

Why is AccountAuthenticator#getAuthToken() not called?

I created my own Android account authenticator by extending AbstractAccountAuthenticator and implementing addAccount() and getAuthToken(). Some of the methods in it are called by AccountManager, but others are not.
This works great:
AccountManager#addAccount()
AccountManager accountManager = AccountManager.get(activity);
accountManager.addAccount(MyAccountAuthenticator.ACCOUNT_TYPE,
MyAccountAuthenticator.AUTHTOKEN_TYPE_FULL_ACCESS, null, null,
activity, callback, null);
The problem happens when I call AccountManager#getAuthToken() in my Activity. The AccountManager does not call the getAuthToken() method I define in my AccountAuthenticator. It calls some other default method that only checks for existence of an authToken before starting the AuthenticatorActivity.
This does not work. It does not call my getAuthToken() method:
AccountManager#getAuthToken()
AccountManager accountManager = AccountManager.get(activity);
accountManager.getAuthToken(
mAccount, MyAccountAuthenticator.AUTHTOKEN_TYPE_FULL_ACCESS, null,
activity, callback, handler);
AuthenticatorService
I created my service and defined onBind(). addAccount() should not work otherwise.
public IBinder onBind(Intent intent) {
return intent.getAction().equals(ACTION_AUTHENTICATOR_INTENT) ? new MyAccountAuthenticator(this).getIBinder() : null;
}
EDIT: I call addAccountExplicitly in MyAuthenticatorActivity after the app gets an auth token back for the user.
Snippet from class MyAuthenticatorActivity extends AccountAuthenticatorActivity:
if (getIntent().getBooleanExtra(KEY_IS_ADDING_NEW_ACCOUNT, false)) {
// Creating the account on the device and setting the auth token we recieved
accountManager.addAccountExplicitly(account, null, null);
}
Your comment cleared things up immensely -- if you set the auth token for the account, then your getAuthToken method will not be called until the token is invalidated. You generally do this by calling invalidateAuthToken upon receiving a 401 or 403 or what have you from the web service.
From the Javadoc for the getAuthToken methods:
If a previously generated auth token is cached for this account and type, then it is returned. Otherwise, if a saved password is available, it is sent to the server to generate a new auth token. Otherwise, the user is prompted to enter a password.
Since your token is in the cache, it is returned directly and your authenticator is not consulted.
for calling AuthenticatorActivity in method AccountManager#getAuthToken, you must send intent to the activity by parcelable, method for example :
final Intent intent = new Intent(mContext, LoginActivity.class);
intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, accountAuthenticatorResponse);
intent.putExtra(LoginActivity.ARG_ACCOUNT_TYPE, account.type);
intent.putExtra(LoginActivity.ARG_AUTH_TYPE, authTokenType);
intent.putExtra(LoginActivity.ARG_ACCOUNT_NAME, account.name);
final Bundle bundle = new Bundle();
bundle.putParcelable(AccountManager.KEY_INTENT, intent);

OSGi DS: Why is setService called before activate

I have a OSGi DS component with properties defined and which is referencing another bundles service. In the setService method I get the reference of the other's bundle service and start another thread. I'm dependent on properties defined in component.xml. Thus the first time I'm able to read the properties from the component.xml file is after the bundle gets the activated method called and getting the reference of the ComponentContext. Now it seems I have serious timing problems, as the setService is executed before the activate is executed.
How can that be? How can the bundle get the required service references before it is even activated?
How can I access the properties defined in the component.xml when starting the thread in the setService method?
The concrete example:
private String publishingUrl = "http://0.0.0.0:11023/ws"; // default address
protected synchronized void activate(ComponentContext context) {
this.ctx = context;
if (ctx != null) {
String url = String.valueOf(ctx.getProperties().get("publishingUrl"));
if (url != null) publishingUrl = url;
}
logger.info("Activated and got the publishingUrl: "+ publishingUrl);
}
public void setService(AnotherService service) {
synchronized (this) {
if (this.anotherService == service) {
logger.info("anotherService was already set.");
return;
} else {
this.anotherService = service;
logger.info("Got anotherService. Thank you DS!");
}
}
startWebserviceThread(publishingUrl);
}
In the console ouput I see the logger message from the setService, then from activate. The method startWebserviceThread is always called with the default value of publishingUrl not with the one got from the ComponentContext property file.
Also it doesn't make a difference if I set immediate="true" or immediate="false" in component.xml
Runtime: Java 1.6, eclipse equinox
The setService() method is used to inject dependencies into your DS.
Then activate() is called, and it is the place where the worker thread should start.
You have to move startWebserviceThread(publishingUrl); at the end of activate() method.
This is also suggested by your logic. You get the publishing url setting from your context, and then you can start your web service. To use another service, you need its reference before starting, so this is why setService() is called before activate().
As noted in this tutorial, a service should not be used inside set/unset methods.

How to solve this exception?

I have been getting this exception, DatabaseObjectNotClosedException:
close() was never explicitly called on database '/data/data/com.project.test/databases/database'
E/SQLiteDatabase(13921): android.database.sqlite.DatabaseObjectNotClosedException:
Application did not close the cursor or database object that was opened here
I tried closing the database helper and cursors, but I will get runtime exception. This happens when I leave the activity and revisit it after hitting the back button.
How can I close my cursors and helpers properly?
I have tried two methods:
first, closing the cursors after each individual use, and closing the database helper onpause.
second, closing the cursors onpause along with the databasehelper, but both didn't work.
can someone help me with this?
EDIT:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
activity = this.getActivity();
context = this.getActivity().getApplicationContext();
layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mDbHelper = new DatabaseHelper(context);
mDbHelper.open();
populateList();
}
public void populateList() {
directoryCursor = mDbHelper.fetchAllRootDirectories();
activity.startManagingCursor(directoryCursor);
adapter = new DirectoryListAdapter(this.getActivity(), directoryCursor);
this.setListAdapter(adapter);
}
......
private UpdateDatabaseListener updateDatabaseListener = new UpdateDatabaseListener() {
public void onUpdate(int from, int to) {
.....
findExistingRecordCursor = mDbHelper.findExistingRecords(from, to);
activity.startManagingCursor(findExistingRecordCursor);
if(findExistingRecordCursor.getCount() == 0) {
....
}
}
}
I have a database helper opened in the onCreate() function.
cursors used when populating the listview,
cursors used to find existing records,
cursors to get information.
UPDATE:
I have tried closing onPause and onDestroy, it still crashes with runtimeexception.
Are you closing the SQLiteDatabase object or not. If not try to close SQLiteDatabase Object like this
SQLiteDatabase db = SQLiteHelper classobject.getWriteableDatabase();
// block of code
db.close();
and run your application.
Could you please post your code so that it will be more helpful to understand your problem.
Sorry for the late reply.
From what I see, you have opened the db using
mDbHelpher.open()
After that you did populatelist()
did you try doing mDbHelpher.close() after that?
Same thing with the cursors. Because your error clearly says that the db or the cursor was left open.
As soon as you are done using the db, you should close. This should not give the problem even after you visit another activity and then press back button.
Also you said you get runtime exception when you close the db or the cursor. Is it the same exception or different?

Categories

Resources