I am working on restoring SMS on KITKAT. Referring to this article I have added the things which are required to set my app as default app for SMS. After adding all required things in manifest file I have write the following code:
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
{
mDefaultSmsApp = Telephony.Sms.getDefaultSmsPackage(mContext);
Intent intent = new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT);
intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME, mContext.getPackageName());
mContext.startActivity(intent);
}
The above code shows this dialog but I am unable to get the result from this activity/dialog either user clicked on Yes or No because I want to add listener or get any code which should represent that the user clicked on these buttons.
Thanks.
One way to do this is to fire the Intent with startActivityForResult(), and then check the resultCode in the onActivityResult() method. Please note that I've changed the code in the example to run in an Activity's Context.
private static final int DEF_SMS_REQ = 0;
private String mDefaultSmsApp;
...
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
{
mDefaultSmsApp = Telephony.Sms.getDefaultSmsPackage(this);
if (!getPackageName().equals(mDefaultSmsApp))
{
Intent intent = new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT);
intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME, getPackageName());
startActivityForResult(intent, DEF_SMS_REQ);
}
}
...
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
switch (requestCode)
{
case DEF_SMS_REQ:
boolean isDefault = resultCode == Activity.RESULT_OK;
...
}
}
As mentioned in a comment below, apparently checking the result code is not 100% reliable. A safer check is to simply compare your app's package name to the current default in onActivityResult(). There's no need to check the result code at all, like the answer linked in the comment shows.
String currentDefault = Sms.getDefaultSmsPackage(this);
boolean isDefault = getPackageName().equals(currentDefault);
The way you can react on "yes" button click:
private String mDefSmsPackage;
#Override
public void onCreate(#Nullable Bundle state) {
//...
mDefSmsPackage = Telephony.Sms.getDefaultSmsPackage(getActivity())
}
#Override
public void onResume() {
super.onResume();
String newDefSmsPkg = Telephony.Sms.getDefaultSmsPackage(getActivity());
if (!TextUtils.equals(mDefSmsPackage, newDefSmsPkg)) {
mDefSmsPackage = newDefSmsPkg;
//ON DEF SMS APP CAHNGE...
}
}
Related
I have an Activity which makes use of KeyguardManager.
The intention is to disallow the user to use the app, if they are unable to successfully supply their credentials.
Though the keyguard intent appears at the start of the app, pressing the device back button moves the intent away, showing the activity which started it.
Overriding the onBackPressed does not seem to help, as it isn't associated with the intent.
#Override
public void onBackPressed() {
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
KeyguardManager km = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
if (km.isKeyguardSecure()) {
setShowWhenLocked(true);
Intent i = km.createConfirmDeviceCredentialIntent("Authentication required", "password");
startActivityForResult(i, CODE_AUTHENTICATION_VERIFICATION);
}
}
What if you use finish() after startActivity() ?
EDIT:
Add finish() on your onActivityResult() if the pattern is false.
What you want to achieve can be done using a "Staging" Activity. For example, you can have a LoginActivity that will check if the user is authenticate or not then from there decide where to redirect him.
The LoginActivity should look something like this, of course you need to adapt it to your business logic :
public class LoginActivity extends AppCompatActivity {
private static final int CODE_AUTHENTICATION_VERIFICATION = 24;
private boolean isFirstLaunch = true;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
isFirstLaunch = false;
//startActivityForResult With your intent to authenticate the user
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == CODE_AUTHENTICATION_VERIFICATION){
Log.i("LOGIN", "return from key guard");
//Check the data and decide if you redirect the user to main activity or not
}
}
#Override
protected void onResume() {
super.onResume();
if(!isFirstLaunch){
Log.i("LOGIN", "resume not first launch");
// the user tried to cancel the authentication either present him with the authentication process again or finish() the activity
}
}
}
Please, N/B: Overriding the onBackPressed does help only when you create a conditional statement controlled by a boolean variable in the onBackPressed method and call it in the onActivityResult i.e when the resultCode != RESULT_OK. Another option is to exit the app when resultCode != RESULT_OK (moveTaskToBack(true)) Here is what I mean below:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == INTENT_AUTHENTICATE) {
if (resultCode == RESULT_OK) {
//do something you want when pass the security
} else //resultCode != RESULT_OK
//Option 1 Ensure you override onBackPressed() with a conditional
//statement controlled by a boolean variable.
onBackPressed();
//Option 2
moveTaskToBack(true); //Exit app when a user click the back button.
}
}
I have two classes Class "A" and Class "B". In class A i have declared a
String password ="admin" .Now in class B i am taking value from user and i
want to change that value of string in class A and want to store value that
user entered. How can i do that? Any help please?
class A
forgetpassword.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent j = new Intent(MainActivity.this,newpassword.class);
startActivity(j);
Class B
EditText newpassword;
Button change;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_new_password);
newpassword = (EditText)findViewById(R.id.newpassword);
change = (Button)findViewById(R.id.chnage);
change.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MainActivity.b= newpassword.getText().toString();
Intent y= new Intent(NewPassword.this,MainActivity.class);
startActivity(y);
}
});
Use StartActivityForResult()
When you intend to get some result back from an Activity you should start activity using startActivityForResult(intent,requestcode)
Its easy Follow these steps
StartActivity
Intent i = new Intent(MainActivity.this, ForgotPasswordActivity.class);
startActivityForResult(i, 1);
Set new password in ForgotPasswordActivity
Now you are in ForgotPasswordActivity, set your new password and return back to MainActivity on Button click like this.
change.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent y= new Intent(NewPassword.this,MainActivity.class);
y.putExtra("someKey",newpassword.getText().toString()); //set new password
setResult(Activity.RESULT_OK, returnIntent); // set your result
finish(); // return back to MainActivity
}
});
Retrive new Password in MainActivity
Now you navigated back to MainActivty to retrieve your new password override onActivityResultMethod().
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1) {
if(resultCode == Activity.RESULT_OK){
String newPassword=data.getStringExtra("someKey");
}
if (resultCode == Activity.RESULT_CANCELED) {
//Write your code if there's no result
}
}
}
Here a link on startActivityForResult()
You can send data from one activity to another in the intent, Use the putExtra() methods the intent class to pass data.Send the data like this
Intent y= new Intent(NewPassword.this,MainActivity.class);
y.putExtra("yourKey",newpassword.getText().toString())
startActivity(y);
and in the onCreate() of MianActivity you can retrieve the value using getStringExtra("yourKey") like this
Intent callingIntent = getIntent();
String password = callingIntent.getStringExtra("yourKey");
and use the password.
Or you can start the NewPassword activity for a result and get the data back in onActivityResult()
Intent newPasswordIntent = new Intent(this,NewPassword.class);
startActivityForResult(newPasswordIntent ,REQUEST_CODE);
and in the change button click handler,
Intent intent= new Intent();
intent.putExtra("yourKey",newpassword.getText().toString());
setResult(Activity.RESULT_OK, intent);
finish();
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
String password = data.getStringExtra("yourKey")
}
Public static variables are easy to call, be aware that they can cause memory leaks
This can lead to context leaking or NPE when you finish the activity.
Instead use an Application class and initialize the string variable in it and with the use of getters() and setters() you can access the variable.
public class BaseApplication extends android.app.Application{
private String admin;
#Override
onCreate(...){
this.admin = "";
}
public String getAdmin(){
return this.admin;
}
public void setAdmin(String admin){
this.admin = admin;
}
}
classA:
...
((BaseApplication) getApplicationContext()).setAdmin("!mpr355!v3");
...
classB:
...
String myAdmin = ((BaseApplication) getApplicationContext()).getAdmin();
...
Also in your manifest file.
<application
android:name=".BaseApplication"
` ...>
UPDATE
Before startActivity(y);
just call
y.putExtra("pass", password);
and in your MainActivity, call getIntent().getStringExtra("pass");
Check for null pointers and you are good to go! :)
Muhammad,
There are many ways to do that and some of the listing here,
Use Broadcast receiver
Use start activity for result
Use static variable
From all of this if you want to change much time then I think broadcast receiver is good one,
Here is the example of broadcast receiver,
In your activity A register broadcast receiver with specific action,
private BroadcastReceiver brodcastRec=new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if(intent!=null && intent.getAction().equals("changePassword")){
String newPassword=intent.getStringExtra("newPassword");
//do whatever you want to do here after getting new password
}
}
};
And then after write following code in your on create of activity A
IntentFilter intentFilter=new IntentFilter("changePassword");
registerReceiver(brodcastRec,intentFilter);
And In your activity B or click event of Button
Intent intent=new Intent();
intent.setAction("changePassword");
intent.putExtra("newPassword","yourValue");
sendBroadcast(intent);
My MainActivity has an EditText with the hint "Weight (lb)", as well as a button that goes to the SettingsActivity. In SettingsActivity, the user is able to change the units used from US to metric. Upon exiting SettingsActivity via the built-in back button on the phone, I want the hint for the EditText to immediately change from "Weight (lb)" to "Weight (kg)".
The farthest I've gotten is using the onBackPressed() method in SettingsActivity. The button press is detected, and the code inside it is executed, but I don't want to change anything related to MainActivity's inside the SettingsActivity class.
Is there an on___() method that I should be using here that I don't know about? Any help would be appreciated.
You can use startActivityForResult for SettingsActivity and after that handle the return result as:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == PICK_CONTACT_REQUEST) {
// Make sure the request was successful
if (resultCode == RESULT_OK) {
// The user picked a contact.
// The Intent's data Uri identifies which contact was selected.
// Do something with the contact here (bigger example below)
}
}
More detail: https://developer.android.com/training/basics/intents/result.html
You can use startActivityForResult for SettingsActivity and after that handle the return result as:
In your MainActivity:
public static int CALL_SETTINGS = 1000;
startActivityForResult(new Intent(this,SettingsActivity.class),CALL_SETTINGS);
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == PICK_CONTACT_REQUEST) {
// Make sure the request was successful
if (resultCode == RESULT_OK) {
// The user picked a contact.
// The Intent's data Uri identifies which contact was selected.
// Do something with the contact here (bigger example below)
}
}
In your Settings Activity:
on backpressed write this:
Intent returnIntent = new Intent();
returnIntent.putExtra("result",data);
setResult(Activity.RESULT_OK,returnIntent);
finish();
Easy option is to store the waitUnit in shared preference and on OnResume() of the Main activity read it from there and update the widget.
You can update the preferences in your Settings activity like below:
preferences = context.getSharedPreferences(context.getString(R.string.preference_file_key),
Context.MODE_PRIVATE);
preferences.edit().putString("unit", "kg");
And you can read this changed value in OnResume() of your Main Activity
preferences.getString("unit", "default unit")
I have a WebActivity that sets a JavascriptInterface for a WebView, on the Interface I have created various methods to be called with Javascript for different tasks, one of them is to send a file through Bluetooth.
The file sends just fine, but I want to inform the user when the file has already been accepted and transmited completely on the other end.
I am trying to use onActivityResult on my main WebActivity and also have tried on the separate class that handles the Bluetooth transmission and has a method called on the JavascriptInterface but I am not getting any callback results after the file is succesfully sent:
//First attempt
public class WebActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
//some code here
//Here I set the interface
myWebView.addJavascriptInterface(new WebAppInterface(this), "Android");
}
#Override
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
if (requestCode == 0) {
//This message is shown after the file transfer has started but no
//finished
Toast.makeText(this, "File Sent", Toast.LENGTH_SHORT).show();
if(resultCode == Activity.RESULT_OK){
//It doesn't work here either I always get Activity.RESULT_CANCELED (0)
//flag afer the file transfer has started
}
}
}
}
//Second Attempt
public class BluetoothTasks {
//code here
private void startTransferIntent() {
//some more code here
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.setType("text/plain");
File file_to_transfer = new File(Environment.getExternalStorageDirectory() +
"/txtTransfer.txt");
intent.putExtra(Intent.EXTRA_STREAM,Uri.fromFile(file_to_transfer));
//some more code here
Activity act = (Activity) mContext;
act.startActivityForResult(intent, TRANSFER_RESULT);
}
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
if (requestCode == TRANSFER_RESULT) {
//Not working here either
//code that is not executed
}
}
}
Could you please tell me if there is a way to do this and if so how would be accomplished?. Thank you.
I have an MainActivity which has two TextView. User has an option to start another activity and choose data from ListView to fill those TextView. My main activity has an OnClickListener which starts an Activty from which user can select data and come back to main activity.My OnClickListener code looks likes this:
private static final int PICK_START = 0;
private static final int PICK_END = 1;
#Override
public void onClick(View v) {
Log.i(MainActivity, "view clicked");
int id = v.getId();
if (id == R.id.searchR) {
//do nothing
} else if (id == R.id.startSearch) {
Intent startIntent = new Intent(this, SList.class);
startActivityForResult(startIntent, PICK_START);
} else if (id == R.id.endSearch) {
Intent startIntent = new Intent(this, SList.class);
startActivityForResult(startIntent, PICK_END);
}
}
When the above onClick method gets called and after that its starts another activity SList.class.In that I have a listview from which user can select the value and upon selecting value the result will be set and activity will finish itself.Code for this is:
sListview.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Station selectedS = sArray.get(position);
Intent returnIntent = new Intent();
returnIntent.putExtra("_id", selectedS.getId());
returnIntent.putExtra("name", selectedS.getName());
setResult(RESULT_OK, returnIntent);
finish();
}
});
In above code activity sets the result and finishes itself.Till here everything is working accordingly.But after that when the previous activity is started, the onActivityResult() method nevers gets called.The code for onActivityResult() is :
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.i(MainActivity, "" + requestCode);
// Make sure the request was successful
if (resultCode == RESULT_OK) {
// Check which request we're responding to
if (requestCode == PICK_START) {
//data.getStringExtra("_id");
Log.i(MainActivity, data.getStringExtra("name"));
} else if (requestCode == PICK_END) {
Log.i(MainActivity, data.getStringExtra("name"));
}
}
}
I dont know why onActivityResult is never triggered .Someone even
wrote on his blog that There is bug in android API. In
startActivityForResult(intent, requestCode); This function does work
as long as requestCode = 0. However, if you change the request code to
anything other than zero, the ApiDemos will fail (and onActivityResult()
won't be called).
I found the solution to my problem.I just needed to restart my eclipse and my code started working.