I have main activity class where i have written takePicturefromCamera() method like this:
public void takePicturefromCamera() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
try {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
mImageCaptureUri = Uri.fromFile(mFileTemp);
}
else {
// The solution is taken from here: http://stackoverflow.com/questions/10042695/how-to-get-camera-result-as-a-uri-in-data-folder
mImageCaptureUri = InternalStorageContentProvider.CONTENT_URI;
}
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, mImageCaptureUri);
intent.putExtra("return-data", true);
startActivityForResult(intent, REQUEST_CODE_TAKE_PICTURE);
} catch (ActivityNotFoundException e) {
Log.d("TAG", "cannot take picture", e);
}
}
Now I have another class where i am doing some cropping part and my requirement is if while cropping user feels that he want to take some another picture instead of previous there i want to call above takePicturefromCamera() method of main activity class on some button click. Can anyone help me how can I do like this. I have tried by doing like this:
retake_button.setOnClickListener(
new View.OnClickListener() {
public void onClick(View v) {
// setResult(RESULT_CANCELED);
main m = new main();
m.takePicturefromCamera();
}
});
But it gives me error NullPointerException at mImageCaptureUri = Uri.fromFile(mFileTemp);
Please help me.
I would suggest you to keep takePicturefromCamera() in separate class, and then call this method passing the activitycontext and data required to it.
Or else you can make Activity2 extend Activity1 and use takePicturefromCamera().
Make that method as static so you can use it anywhere in your application.
Also add one more parameter "File" to your function. By this, you also have flexibility to use the same function for different file object in your application.
Hope this will help you.
Related
So i am new to android and java, and i understand that i should move between activities with intents.
Intent randomintent = new Intent(profile.this, loggedactivity.class);
randomintent .putString("name", namestring);
startActivity(randomintent);
The thing is, that i also have a function that i want it to be executed just before this intent takes the user to another activity. So my code looks something like this.
btnUpload.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
uploadImage();
//this uploads the image, it works without the intent i added
infosendstuff();
//this should be executed after the image is uploaded and stores the image link to a database (also works)
Intent randomintent = new Intent(profile.this, loggedactivity.class);
randomintent .putString("name", namestring);
startActivity(randomintent);
}
});
The problem seems to be the intent, when used, it ignores the other two functions above it, that upload the picture and store the link for that picture.
The goal is to upload the picture, once done, get the link, send the link to another activity though the intent (with the bundle) and thats about it.
it's better to use AsynkTask.
create a class, it should extend from AsynkTask. in doInBackground, upload your photos, process the response and send the link. and in onPostExecute method, go to the other activity.
update 1
class myClass extends AsyncTask<Void,Void,Void>{
#Override
protected Void doInBackground(Void... params) {
String result = uploadPhotos();
proccess result;
send links;
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
Intent randomintent = new Intent(profile.this, loggedactivity.class);
randomintent .putString("name", namestring);
startActivity(randomintent);
}
}
now you can use it like this:
new myClass().execute();
but before coding, i think you need to study more about web Connection process in android.
It seems that uploadImage() Method does some stuff on the network and since the network request and response is done in another thread the code continue to execute and loggedactivity will show before the uploadImage() method is done.
So one way is that you force main thread to wait for network thread and after the network thread is done main thread continue to work but it cause the UI thread to freeze.
another way is that you should use callbacks that when the uploadImage() method is done some method will invoke and in that method you start your new activity. something like code below :
uploadImage(new ResponeListener() {
#override
public void onDataReady(String nameString) {
Intent randomintent = new Intent(profile.this,loggedactivity.class);
Bundle b = new Bundle();
b.putString("name", namestring);
startActivity(randomintent);
}
}
Please i will like to have a method/function in a separate class
that will enable me to go to next activity or fragment class when i call it
here is my little try of code
inside my go_to.class i have this below
for activity
void goToActivity(Activity t){
startActivity(new Intent(this, t.class));
}
void goToFragment(Fragment f,package.com.R l){
getSupportFragmentManager().beginTransaction().add(l,new f).commit();
}
and to use example
goToActivity(mynextactivity.class);
goToFragment(mynextfragment.class,R.id.fragment_layout);
Any help is welcome
From non activity class you can create a function it like this:
public static void goToHomeActivity(Context context)
{
Intent i = new Intent(context, ActivityDashboard.class);
context.startActivity(i);
}
Then call it like this MyUtils.goToHomeActivity(context);
Alternatively, from activity class like this:
private void goToHomeActivity()
{
Intent i = new Intent(getBaseContext(), ActivityDashboard.class);
context.startActivity(i);
}`
Then call it like this goToHomeActivity();
I later solve it this way after many trial:
What i am trying to achive is to have a function to call new activity class and fragment when a button is clicked on at runtime
void goToActivity(Class t){
startActivity(new Intent(this, t));
}
my where i have been getting the fragment concept wrong is fragment is not indepent activity class, so to overcome fragment need anactivity parent or root layout to hold the fragment layout that is you can never start fragment instance alone like activity which is very big issure for begginers to understand
void goToFragment(Fragment f){
fragmentTransaction.replace(R.id.your_layout, f);
fragmentTransaction.addToBackStack(null);
}
or if you cannot determine your xml layout you can write it like this:
void goToFragment(int l,Fragment f){
fragmentTransaction.replace(l, f);
fragmentTransaction.addToBackStack(null);
}
Thank you all for your help
I have a crash report of the same error like in this question: WebView methods on same thread error
There it is suggested to create a Runnable().
I don't understand why exactly this solves the problem. The error says "Webview methods on same Thread", but the answer suggests to create the method on the UI-Thread (Main Thread). But isn't the UI-Thread the one and only thread? Could someone explain this whole process in detail (considering I create a new Webview in every activity in the constructor)?
My code to implement Javascript functions/methods looks like this:
public class JS_Bind {
private static final String TAG = "JS_Bind";
private Context context;
private AdvancedWebView mWebView;
public JS_Bind(Context c, AdvancedWebView mWebView) {
context = c;
this.mWebView = mWebView;
}
#JavascriptInterface
public void openActivity(String activityName) {
try {
Class activityClass = Class.forName(PACKAGE_NAME + "." + activityName);
context.startActivity(new Intent(MainActivity.this, activityClass));
} catch (ClassNotFoundException e) {
Toast.makeText(context, "Invalid activity name: " + activityName, Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
#JavascriptInterface
public void makeToast(String toast) {
Toast mToast = Toast.makeText(context, toast, Toast.LENGTH_SHORT);
mToast.setGravity(Gravity.CENTER, 0, 0);
mToast.show();
}
#JavascriptInterface
public void external(String url) {
mTracker.send(new HitBuilders.EventBuilder().setCategory("Action").setAction("External Link: " + url).build());
Uri uri = Uri.parse(url);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
}
#JavascriptInterface
public String showToken() {
return gcmToken;
}
#JavascriptInterface
public int showUid() {
SharedPreferences pref = getSharedPreferences("Pref", Activity.MODE_PRIVATE);
int uid = pref.getInt("uid", 0);
return uid;
}
#JavascriptInterface
public void buyPremium() {
bp.purchase(MainActivity.this, PRODUCT_ID);
}
}
Do I have to change EVERY function to this code (first answer in the question I refered to):
#JavascriptInterface
mWebView.post(new Runnable() {
#Override
public void makeToast() {
// ...
}
});
?
By the way, this is how I create the webview in the constructor activies onCreate method:
mWebView = (AdvancedWebView) findViewById(R.id.webView);
mWebView.setListener(this, this);
mWebView.addJavascriptInterface(new JS_Bind(this, mWebView), "Android");
mWebView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
if (!DetectConnection.checkInternetConnection(this)) {
mWebView.loadUrl("file:///android_asset/offline.html");
}
else {
mWebView.loadUrl("http://example.com/tw3/index.php?s=home");
}
But isn't the UI-Thread the one and only thread?
No. WebView has its own pool of threads. There can be many other threads in an Android application.
Do I have to change EVERY function to this code
Not necessarily.
First, I do not see how you are getting that error (A WebView method was called on thread 'JavaBridge'. All WebView methods must be called on the same thread.) from your #JavascriptInterface methods shown above. That error is when you call a method on the WebView itself, and you are not doing that.
You will need to use runOnUiThread() (or equivalent techniques) if:
Your #JavascriptInterface methods refer to the WebView itself, or
Your #JavascriptInterface try to do something else that has to be done on the main application thread (which will yield a different error message, as it will not be tied specifically to WebView)
Your startActivity() call might need to be called on the main application thread — I forget if that can be called on a background thread or not. Similarly with your Toast work — while I think that can be done on a background thread, I am not certain of it. It has been ages since I tried doing either of those things from a background thread.
Also, please only use your code if you control every single byte of what is being displayed in the WebView. Exposing startActivity() to arbitrary Web content has significant security implications.
Usually you would start an activity with something like the following:
private void llMenuSettings_Click() {
this.runOnUiThread(new Runnable() {
public void run() {
Intent intent = new Intent(XXXXXXXX.this, View_Settings.class);
startActivity(intent);
XXXXXXXX.this.finish();
}
});
}
However I am extending a LinearLayout:
public class MenuContainer extends LinearLayout {
}
Therefore I have run into a couple of issues:
How would you know what XXXXXXXX is in the example as the LinearLayout can be included in multiple Layouts?
startActivity() does not exist in a LinearLayout class?
There are a few similar questions but none that fully answer the above scenario therefore hoping this can be answered and help others in the future?
Inside your LinearLayout extending class, you could create the following method:
public void launch() {
Intent i = new Intent(getContext(), YourActivity.class);
getContext().startActivity(i);
}
Use the getContext() method inside your customview to retrieve the Context and start a new Activity.
I am very new with android development. My app has a lot of views/Activity and user can jump from one view to another depending his/hers inputs. so i thought of creating an interface IView which will have a function
void openNewView(Class viewClass);
and the function in the view class would look something like this
public void openNewView(Class viewClass)
{
Intent intent = new Intent(this, viewClass.class);
startActivity(intent);
}
The whole idea is that my controller can listen for user inputs and then call openNewView as per the requirement.
The issue that i am facing is with java not accepting a parameter of type Class
What is it that i am doing wrong here. is there a work around what i am trying to achieve.
One good approach would be extend all your activities from an abstract Activity like this:
public abstract class BaseActivity {
//....
public void openNewView(Class viewClass) {
Intent intent = new Intent(this, viewClass.class);
startActivity(intent);
}
}
Doing this way you don't have to copy your code in every activities and keep code clean.
try by adding current Context param in openNewView method as:
void openNewView(Class viewClass,context);
and in your function :
public void openNewView(Class viewClass,Context context)
{
Intent intent = new Intent(context, viewClass.class);
context.startActivity(intent);
}