Android bugs on device. What should I do to fix them? [closed] - java

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
In my application I noticed these three things:
-The back button is enabled when going from one activity to another enabling the user to click on back to the original activity. The problem is I don't want the user to click on Back at a certain point in my application. I don't want to disable the back button completely in my application, only when one intent is called. How can I do that?
-I noticed something strange... when a toast notification pops up in my application all is well until I exit my application. When I exit my application, some of the toast notifications are residual and are popping outside of my application. Is there a reason for that? Did I miss something in the activity lifecycle to handle the cancellation of toasts at a certain point?
Lastly, this one is rather tough to solve. How do I lock my screen so that when the user rotates the device, that the activity doesn't not get called again and the asynctask can still resume without starting over again?
Thanks a lot for your time. Just curious why these things happen and what should I look into?
Here's my code:
//Main Activity.java
package com.example.Patient_Device;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import java.io.*;
public class MainActivity extends Activity {
//fields
private ProgressDialog progressBar;
private Context context;
/**
* Called when the activity is first created.
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.start_setup);
//Set the context
context = this;
//Initialize the start setup button and add an onClick event listener to the button
final Button start_setup_button = (Button) findViewById(R.id.start_setup_button);
start_setup_button.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
//Executes the AsyncTask
new RetrieveInfoTask().execute();
//Instantiates the intent to launch a new activity
Intent myIntent = new Intent(MainActivity.this, RetrieveInfoActivity.class);
MainActivity.this.startActivity(myIntent);
}
});
}
public class RetrieveInfoTask extends AsyncTask<Void, Void, Void> {
//Called on the UI thread to execute progress bar
#Override
protected void onPreExecute() {
super.onPreExecute();
progressBar = new ProgressDialog(context);
progressBar.setIndeterminate(true);
progressBar.setCancelable(false);
progressBar.setMessage(MainActivity.this.getString(R.string.retrieve_info));
progressBar.show();
}
//Methods that retrieves information from the user device. This is performed in the Background thread
private void retrieveInfo() {
try {
//Reading the drawable resource line by line
String str="";
StringBuffer buf = new StringBuffer();
InputStream is = MainActivity.this.getResources().openRawResource(R.drawable.user_info);
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
if (is!=null) {
while ((str = reader.readLine()) != null) {
buf.append(str + "\n" );
}
}
is.close();
} catch (Exception e) {
e.printStackTrace();
}
}
//doInBackground calls retrieveInfo() to perform action in Background
#Override
protected Void doInBackground(Void... params) {
retrieveInfo();
return null;
}
//When the background task is done, dismiss the progress bar
#Override
protected void onPostExecute(Void result) {
if (progressBar!=null) {
progressBar.dismiss();
}
}
}
}
//RetrieveInfoActivity.java
package com.example.Patient_Device;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Resources;
import android.os.BatteryManager;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;
public class RetrieveInfoActivity extends Activity {
private static String TAG = "RetrieveInfoActivity";
private Context context;
String fileLastSync = "09-18-2014 03:47 PM";
#Override
public void onCreate(Bundle savedInstanceState) {
context = this;
super.onCreate(savedInstanceState);
setContentView(R.layout.retrieve_info);
//Once the new activity is launched, the setup is complete
Toast.makeText(getApplicationContext(), "Setup Complete!",
Toast.LENGTH_LONG).show();
//Gets the 'last synced' string and sets to datetime of the last sync
Resources resources = context.getResources();
String syncString = String.format(resources.getString(R.string.last_sync), fileLastSync);
//Dynamically sets the datetime of the last sync string
TextView lastSyncTextView = ((TextView) findViewById(R.id.last_sync) );
lastSyncTextView.setText(syncString);
//calls registerReceiver to receive the broadcast for the state of battery
this.registerReceiver(this.mBatInfoReceiver,new
IntentFilter(Intent.ACTION_BATTERY_CHANGED));
}
private BroadcastReceiver mBatInfoReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context arg0, Intent intent) {
//Battery level
int level = intent.getIntExtra("level", 0);
//Dynamically sets the value of the battery level
TextView batteryTextView = ((TextView) findViewById(R.id.battery) );
batteryTextView.setText("Battery Level: " + String.valueOf(level)+ "%");
//If the battery level drops below 25%, then announce the battery is low
//TODO: Add 25 to constants file.
if(level < 25) {
Toast.makeText(getApplicationContext(), "Low Battery!",
Toast.LENGTH_LONG).show();
}
//Plugged in Status
int plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
//Battery Status
int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
//If the device is charging or contains a full status, it's charging
boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
status == BatteryManager.BATTERY_STATUS_FULL;
//If the device isCharging and plugged in, then show that the battery is charging
if(isCharging && plugged == BatteryManager.BATTERY_PLUGGED_AC || plugged == BatteryManager.BATTERY_PLUGGED_USB) {
Toast.makeText(getApplicationContext(), "Charging.." + String.valueOf(level)+ "%",
Toast.LENGTH_LONG).show();
}else{
Toast.makeText(getApplicationContext(), "Unplugged!",
Toast.LENGTH_LONG).show();
}
}
};
#Override
public void onDestroy() {
try {
super.onDestroy();
unregisterReceiver(this.mBatInfoReceiver);
}
catch (Exception e) {
Log.e(RetrieveInfoctivity.TAG, getClass() + " Releasing receivers-" + e.getMessage());
}
}
}
//StartSetupActivity.java
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class StartSetupActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}
//FragmentsActivity.java
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class FragmentsActivity extends Fragment{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.main, container, false);
}
}

First of all whenever you want to disable back press just override onBackPressed() method and remove super. like this:
#Override
public void onBackPressed() {
//super.onBackPressed();
}
Second you'r using application context to show toast. use activity context.
Toast.makeText(this or YourActivity.this, "Setup Complete!", Toast.LENGTH_LONG).show();
Third just add this attribute into your manifest class. This will avoid recrating your activity when orientation change
android:configChanges="orientation"

I'll answer these in order:
Back Button
You can override onBackPressed in your Activity and determine if you want to consume it or let Android process it.
#Override
public void onBackPressed()
{
// Set this how you want based on your app logic
boolean disallowBackPressed = false;
if (!disallowBackPressed)
{
super.onBackPressed();
}
}
Toasts
Toasts are enqueued with the Notification Manager. If you show multiple Toasts in a row, they get queued up and shown one at a time until the queue is empty.
Locking Orientation For Activity
Use android:screenOrientation="landscape" or android:screenOrientation="portrait" on your activity element in your manifest to lock the orientation.

I think that these questions should be asked separately, because the answer in detail to every item of your question is too long, but I hope this helps:
-The back button is enabled when going from one activity to another enabling the user to click on back to the original activity. The
problem is I don't want the user to click on Back at a certain point
in my application. I don't want to disable the back button completely
in my application, only when one intent is called. How can I do that?
You can override the onBackPressed on the activities you don't want the user to go back.
#Override
public void onBackPressed() {
//Leave it blank so it doesn't do anything
}
-I noticed something strange... when a toast notification pops up in my application all is well until I exit my application. When I exit my
application, some of the toast notifications are residual and are
popping outside of my application. Is there a reason for that? Did I
miss something in the activity lifecycle to handle the cancellation of
toasts at a certain point?
I think that the reason behind that is that toast go into a que, and are showed in order, even if the app is no longer visible.
Lastly, this one is rather tough to solve. How do I lock my screen so
that when the user rotates the device, that the activity doesn't not
get called again and the asynctask can still resume without starting
over again?
For this, you can use the following code in your manifest
android:configChanges="orientation|screenSize"/>
However this is NOT recommended by google, I suggest you read the following link to get a little more information on how to handle orientation changes:
http://developer.android.com/guide/topics/resources/runtime-changes.html

Related

How to solve Photopicker error in android Studio?

I have the following code , im receiving an error :
enter image description here
package com.example.photopicker;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.PickVisualMediaRequest;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
Button addimage;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
addimage=findViewById(R.id.button_pick_photo);
addimage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Registers a photo picker activity launcher in single-select mode.
ActivityResultLauncher<PickVisualMediaRequest> pickMedia =
registerForActivityResult(new ActivityResultContracts.PickVisualMedia(), uri -> {
// Callback is invoked after the user selects a media item or closes the
// photo picker.
if (uri != null) {
Log.d("PhotoPicker", "Selected URI: " + uri);
} else {
Log.d("PhotoPicker", "No media selected");
}
});
// Include only one of the following calls to launch(), depending on the types
// of media that you want to allow the user to choose from.
// Launch the photo picker and allow the user to choose images and videos.
pickMedia.launch(new PickVisualMediaRequest.Builder()
**.setMediaType(new ActivityResultContracts.PickVisualMedia.ImageAndVideo())**
.build());
}
});
}
}
This code i got it from the Android developer Website :
https://developer.android.com/training/data-storage/shared/photopicker
but Doesnt seem to work , and im not able to find any online solution.
Try replacing:
new ActivityResultContracts.PickVisualMedia.ImageAndVideo()
with:
ActivityResultContracts.PickVisualMedia.Companion.getImageAndVideo()
ImageAndVideo is a Kotlin object — it is not a class that you instantiate yourself. However, the source code lacks the #JvmField annotation, so I think that just referring to ActivityResultContracts.PickVisualMedia.ImageAndVideo will fail, as outlined in the docs.

How do I get back to the start page with a button?

I'm trying to develop a game app. At the gameover screen, I want to have a button that goes back to the start when you click it. But the problem is, it doesn't work. I really don't know why it doesn't work, I have tried everything but can't find the problem. Can someone help me?
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import androidx.appcompat.app.AppCompatActivity;
public class GameOver extends AppCompatActivity {
MediaPlayer gameoversound;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.gameover);
Button weiter_button = (Button) findViewById(R.id.weiter);
weiter_button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) { goToMainActivity(); }
});
}
private void goToMainActivity() {
Intent back = new Intent( this, MainActivity.class);
startActivity(back);
}
}
Change this to GameOver.this
You don't have to cast widgets explicitly anymore, except for some special cases. It has been this way for a while.
If the game is over, you'd best insert a finish(); after launching the main Activity. You don't want users to be able to go back to the gameover screen by pressing the back button.
Set up FLAGS for your Intents. This comes in handy because if you didn't finish(); some Activity it remains in the stack, so it will be launching that one, but then you might want a new one. This will cause issues in navigation.
Add/ check your onBackPressed() methods for the 2 Activities.
Furthermore, specify that you are overriding the method
#Override
public void onClick(View view)
{
}
In the XML, <Button> tag, add
android:clickable=true
android:focusable=true

TextView not updating after creating new Activity

I'm new to Android and I stuck. I have a Textview on Activity which should show result, but for some reason it is updating TextView only if you click on Button which is not doing anything or if you close app and reopen it again from menu of running apps. I suppose it's somehow connected with updating activity. Thank you in advance!
package com.example.visacheck;
import android.content.Intent;
import android.os.Bundle;
import android.webkit.JavascriptInterface;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class FourthActivity extends AppCompatActivity {
String aplicationNumber;
String type;
String year;
#Override
protected void onCreate(Bundle savedInstanceState) {
this.getSupportActionBar().hide();
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fourth);
Intent intent = getIntent();
final Button button = findViewById(R.id.resultButton); //Result appearing only after clicking button
aplicationNumber = intent.getStringExtra("aplicationNumber");
type = intent.getStringExtra("type");
year = intent.getStringExtra("year");
class MyJavaScriptInterface {
#JavascriptInterface
#SuppressWarnings("unused")
public void processHTML(String html) {
TextView text = findViewById(R.id.textView);
text.setText(html);
}
}
final WebView myWebview = findViewById(R.id.webview);
myWebview.getSettings().setJavaScriptEnabled(true);
myWebview.addJavascriptInterface(new MyJavaScriptInterface(), "HTMLOUT");
myWebview.setWebViewClient(new WebViewClient() {
#Override
public void onPageFinished(WebView view, String url) {
myWebview.loadUrl(("javascript:document.getElementById('edit-ioff-application-number').value = '" + aplicationNumber + "';void(0);"));
myWebview.loadUrl(("javascript:" + "document.getElementById('edit-ioff-application-code').value = '" + type + "';void(0);"));
myWebview.loadUrl(("javascript:document.getElementById('edit-ioff-application-year').value = '" + year + "';void(0);"));
myWebview.loadUrl(("javascript:document.getElementById('edit-submit-button').click();"));
myWebview.loadUrl("javascript:window.HTMLOUT.processHTML(document.getElementsByClassName('alert alert-warning')[0].innerText);");
myWebview.loadUrl("javascript:window.HTMLOUT.processHTML(document.getElementsByClassName('alert alert-success')[1].innerText);");
myWebview.loadUrl("javascript:window.HTMLOUT.processHTML(document.getElementsByClassName('alert alert-danger')[0].innerText);");
}
});
myWebview.loadUrl("https://frs.gov.cz/ioff/application-status");
}
}
I'm not going to do a very good job at this, as I can hardly touch on the subject myself. Maybe someone with more knowledge can go into further detail, but the general idea here is that this code is being called by the JS thread as opposed to your UI thread (Which is the only thread that is allowed to handle UI updates), and I'm surprised this code doesn't crash when doing so, honestly. The post() method adds this to the view's message queue, which means that the text will be updated AFTER the view has been rendered, and has no other tasks to perform. I know I did a bad job at explaining this, but for more information, please refer to these:
What exactly does the post method do?
Alternately, you can user runOnUIThread(), example:
How do we use runOnUiThread in Android?
I'm sure that a lot of people out there have already explained this better than I have. But the most important thing to understand here is that you must not update UI from anything other than the UI thread
Please note that I chose myWebView arbitrarily, and this should work if posted to the fragment's main view aswell.
class MyJavaScriptInterface {
#JavascriptInterface
#SuppressWarnings("unused")
public void processHTML(final String html) {
myWebview.post(new Runnable() {
#Override public void run() {
TextView text = findViewById(R.id.textView); text.setText(html);
}
});
}
}

How can I keep an android app running in background

I am making a simple scare your friend app. You have to press a button and then set a minute timer that will then bring up classic exorsist icon and scream on screen. I tried putting android:persistent="true", but it didn't work...
Here's my activity:
package com.odysseus.myapp;
import android.app.Activity;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends Activity {
MediaPlayer scareMusic;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button startTimer = (Button) findViewById(R.id.btimerStart);
scareMusic = MediaPlayer.create(MainActivity.this, R.raw.monster_scream);
startTimer.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Thread scareTimer = new Thread(){
public void run(){
try{
sleep(5000);
Intent activityIntent = new Intent("com.odysseus.myapp.SCARER");
startActivity(activityIntent);
}catch(InterruptedException e){
e.printStackTrace();
}
}
};
scareTimer.start();
}
});
}
}
I am really new to android so don't just say use a service or something because I don't know what that is. Other answers I found were too advanced for me so please explain as much as you can!
There's no way to truly make your app immune to shutdown. The attribute "android:persistent" gets ignored for all apps that are not System apps.
That being said, to make sure that the application fires the intent after the given time, you'll probably have to place the launching code in a serivce (if even possible then).
Instead of using Activity you can use a Service that always run in the background. See this answer for how to create a app that just has an activity. Android app with Service only. As an work around you can create an Activity no content view or transparent layout, then in this activity start the service and then quickly close the activity using finish().
Now in the Service you can use the exact code that you are trying to use in an Activity. But remember to stop the Service after showing com.odysseus.myapp.SCARER.
Update :-
In your com.odysseus.myapp.SCARER activity after showing the code you can use the following command to stop the Service.
stopService(new Intent(this, service.class));
To use services is not really hard. Just create a new class and add extends Service. When you're done doing that you should add this method:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//Your code here
return START_STICKY;
}
Inside this method you can launch your media player. To stop the service you just put stopSelf() in the onDestroy(). Good luck!

Button to vibrate makes android app force close

Im just making a simple app that will vibrate when the button is clicked, but for some reason when i click the button the app says it unexpectedly stopped and needed to force close, below is the source code to the main java file and i have used the android vibrate permission in my manifest. can someone tell me why every time I click the vibrate button it gives me the error that it unexpectedly stopped?
package com.test;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Vibrator;
import android.view.View;
import android.widget.EditText;
public class Main extends Activity {
public final static String EXTRA_MESSAGE = "com.test.MESSAGE";
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
/* Called when the user clicks the button */
public void sendMessage(View view) {
// do something in response to button
Intent intent = new Intent(this, DisplayMessageActivity.class);
EditText editText = (EditText) findViewById(R.id.edit_message);
String message = editText.getText().toString();
intent.putExtra(EXTRA_MESSAGE, message);
startActivity(intent);
}
public void vibrateMe() {
Vibrator vibrate = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
vibrate.vibrate(500);
}
public void stopVibrating(Vibrator vibrate) {
vibrate.cancel();
}
}
You have to change your vibrateMe() to vibrateMe(View v) if you use android:onClick="vibrateMe"
For instance, if you specify android:onClick="sayHello", you must
declare a public void sayHello(View v) method of your context
(typically, your Activity).
Check the developer page
public void stopVibrating(Vibrator vibrate) {
vibrate.cancel();
}
remove this and then check.

Categories