I'm about to launch my app.
I wrote a code for inApp immediate update since I want everyone who downloaded my app to update when I upload updated version.
I wonder if this code will work without causing any problem.
mAppUpdateManager = AppUpdateManagerFactory.create( this );
Task<AppUpdateInfo> appUpdateInfoTask = mAppUpdateManager.getAppUpdateInfo();
appUpdateInfoTask.addOnSuccessListener( new OnSuccessListener<AppUpdateInfo>() {
#Override
public void onSuccess(AppUpdateInfo result) {
if (result.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
&& result.isUpdateTypeAllowed( AppUpdateType.IMMEDIATE )){
try {
mAppUpdateManager.startUpdateFlowForResult( result, AppUpdateType.IMMEDIATE, MainActivity.this, MY_REQUEST_CODE );
} catch (IntentSender.SendIntentException e) {
Log.e( "AppUpdater", "AppUpdateManager Error", e );
e.printStackTrace();}
}else {}
}
} );
Please mention the issue you're facing. Meanwhile you can use this library to introduce in-app updates in your app. It's pretty simple to use and tested properly.
https://github.com/sohanzz/Easy-InApp-Updater
Related
I'm trying to make an app on android studio that can customize the user's hotspot name (SSID), but found that WifiConfiguration was deprecated. I'm not sure about the difference between "NetworkSpecifier" and "WifiNetworkSuggestion", and how to use them to fix this. I'm new to android studio and I couldn't find a similar solution. Can anyone teach me what should I do? Or is it possible to customize it?
`
public void configureHotspot(String name) {
WifiConfiguration apConfig = new WifiConfiguration();
apConfig.SSID = name;
apConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
try {
Method setConfigMethod = mWifiManager.getClass().getMethod("setWifiApConfiguration", WifiConfiguration.class);
boolean status = (boolean) setConfigMethod.invoke(mWifiManager, apConfig);
Log.d(TAG, "setWifiApConfiguration - success? " + status);
} catch (Exception e) {
Log.e(TAG, "Error in configureHotspot");
e.printStackTrace();
}
}
`
This part of the code is from this example: "https://github.com/aegis1980/WifiHotSpot", in "MyOreoWifiManager.java".
(this is the only example I found that can successfully turn on my phone's hotspot.)
I think I could keep the try-and-catch part because "WifiManager" is not deprecated, so maybe the problem is at apConfig only.
I am using Android UpdateManager to get information about my app update and perform auto update.
I am calling below code in my MainActivity.onCreate. The problem is some of my devices get the update information and display the update activity, but some not. All the devices have Google Play Services installed. What may be the reason of UpdateManager not working consistently?
AppUpdateManager appUpdateManager = AppUpdateManagerFactory.create(this);
// Returns an intent object that you use to check for an update.
Task<AppUpdateInfo> appUpdateInfoTask = appUpdateManager.getAppUpdateInfo();
// Checks that the platform will allow the specified type of update.
appUpdateInfoTask.addOnSuccessListener(appUpdateInfo -> {
if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
// For a flexible update, use AppUpdateType.FLEXIBLE
&& appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE)) {
// Request the update.
try {
appUpdateManager.startUpdateFlowForResult(appUpdateInfo, AppUpdateType.IMMEDIATE, this, REQUEST_CHECK_FOR_APP_UPDATE);
} catch (IntentSender.SendIntentException e) {
Logger.log(Logger.error, e.getMessage());
}
}
});
appUpdateInfoTask.addOnFailureListener(e -> {
Logger.log(Logger.error, e.getMessage());
});
I've got a really odd problem with the Google Drive Android SDK. I've been using it for several months now, and until last week it performed perfectly. However, there is now a really odd error, which doesn't occur all the time but does 9 out of 10 times.
I'm trying to list the user's files and folders stored in a particular Google Drive folder. When I'm trying to use the method Drive.files().list().execute(), 9 out of 10 times literally nothing happens. The method just hangs, and even if I leave it for an hour, it just remains doing... nothing.
The code I'm using is below - all of this being run within the doInBackground of an AsyncTask. I've checked credentials - they are all fine, as is the app's certificate's SHA1 hash. No exceptions are thrown. Google searches have yielded nothing. Here is the particular bit of code that's bothering me:
try {
GoogleAccountCredential credential = GoogleAccountCredential.usingOAuth2(
SettingsActivity.this, Arrays.asList(DriveScopes.DRIVE));
if (googleAccountName != null && googleAccountName.length() > 0) {
credential.setSelectedAccountName(googleAccountName);
Drive service = new Drive.Builder(AndroidHttp.newCompatibleTransport(),
new GsonFactory(), credential).build();
service.files().list().execute(); // Google Drive fails here
} else {
// ...
}
} catch (final UserRecoverableAuthIOException e) {
// Authorisation Needed
runOnUiThread(new Runnable() {
#Override
public void run() {
try {
startActivityForResult(e.getIntent(), REQUEST_AUTHORISE_GDRIVE);
} catch (Exception e) {
Log.e("SettingsActivity: Google Drive", "Unable to add Google Drive account due to Exception after trying to show the Google Drive authroise request intent, as the UserRecoverableIOException was originally thrown. Error message:\n" + e.getMessage());
}
}
});
Log.d("SettingsActivity: Google Drive", "UserRecoverableAuthIOException when trying to add Google Drive account. This is normal if this is the first time the user has tried to use Google Drive. Error message:\n" + e.getMessage());
return;
} catch (Exception e) {
Log.e("SettingsActivity: Google Drive", "Unable to add Google Drive account. Error message:\n" + e.getMessage());
return;
}
I'm using Drive API v2. Thanks everyone!
Edit
Having played around a bit more, it turns out this isn't for just listing files. Trying to interact with any file on Google Drive behaves the same way - deleting, downloading, creating... Anything! I have also noticed that putting the device in aeroplane mode so it has not internet access makes no difference either: Google Drive doesn't throw an exception, or even return, it just freezes the thread it's on.
I've updated to the very latest Drive API lib but that hasn't helped. I remembered that the error happened soon after I added the JSch SSH library to the project, so I removed that, but it made no difference. Removing and re-adding the Drive API v2 has made no difference either, and nor has cleaning the project.
Edit 2
I've found something which may be significant. On the Google Developer console, I had some Drive errors recorded as follows:
TOP ERRORS:
Requests % Requests Methods Error codes
18 38.30% drive.files.list 400
14 29.79% drive.files.insert 500
11 23.40% drive.files.update 500
4 8.51% drive.files.get 400
Do you reckon these are the errors? How could I fix them? Thanks
This is my code and it's work
new AsyncTask<Void, Void, List<File>>() {
#Override
protected List<File> doInBackground(Void... params) {
List<File> result = new ArrayList<File>();
try {
com.google.api.services.drive.Drive.Files.List list = service.files().list();
list.setQ("'" + sourcePath + "' in parents");
FileList fileList = list.execute();
result = fileList.getItems();
if(result != null) {
return result;
}
} catch (UserRecoverableAuthIOException e) {
startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(List<File> result) {
//This is List file from Google Drive
};
}.execute();
I've come up with a solution which does work, and thought I'd post it so others could see it if they happen to come across the problem.
Luckily, I had backed up all of the previous versions of the app. So I restored the whole project to how it was two weeks ago, copied and pasted all changes from the newer version which had been made since then, and it worked. I don't see why this should work, since the end result is the same project, but it does!
Google Drive List Files
This might help you.. Try to display it in ListView u will see all fetched folders
public void if_db_updated(Drive service)
{
try {
Files.List request = service.files().list().setQ("mimeType = 'application/vnd.google-apps.folder'");
FileList files = request.execute();
for(File file : files.getItems())
{
String title = file.getTitle();
showToast(title);
}
} catch (UserRecoverableAuthIOException e) {
startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
} catch (IOException e) {
e.printStackTrace();
}
}
public void showToast(final String toast) {
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), toast, Toast.LENGTH_SHORT).show();
}
});
I am attempting to integrate the Dropbox chooser drop-in api into my application. I am running into an abnormal issue. In my app when I launch the dbx chooser, anytime that I select a file the application fails with the following error code:
Sorry, an error has occurred. Please try again later.
Here is the portion of my code that implements the Dropbox API. This portion of the code is where the dropbox api is initially invoked.
public void StartDropboxApplication() {
// create the chooser
DbxChooser chooser = new DbxChooser(APP_KEY);
DbxChooser.ResultType result;
// determine which mode to be in // TODO REMOVE ALL BUT FILE CONTENT TODO SIMPLIFY by making this a setting
switch(( (RadioGroup) ParentActivity.findViewById(R.id.link_type)).getCheckedRadioButtonId() ) {
case R.id.link_type_content:
result = DbxChooser.ResultType.DIRECT_LINK;
break;
default:
throw new RuntimeException("Radio Group Related error.");
}
// launch the new activity
chooser.forResultType(result).launch(ParentActivity, 0);
}
Here is the position where the code should then pick it up although it never does.
protected void onActivityResult( int request, int result, Intent data ) {
Log.i(fileName, "result: " + result);
// check to see if the camera took a picture
if (request == 1) {
// check to see if the picture was successfully taken
if (result == Activity.RESULT_OK) {
onPicture();
} else {
Log.i(fileName, "Camera App cancelled.");
}
} else if (request == 0) {
if ( result == Activity.RESULT_OK ) {
onDropbox(data);
} else {
Log.i(fileName, "dropbox related issue.");
}
}
}
Thank you for any help or suggestions that you are able to provide.
I was able to solve my own issues and get this working. On the off chance that someone else has a similar problem I will detail the solution. The first issue was I was that my APP_KEY was incorrect.
The next issue was that I was attempting to read from a direct link instead of a content link. The direct link provides the application with a link to the file on the Dropbox server whereas the content link provides the application with a cached version of the file. If the file is not present on the device, the SDK downloads a copy for you.
I did a mistake that apparently can be solved only by uninstalling and then installing my app again.
I delivered a message to the users, but no-one seems to uninstall it.
AFAIK, if I change the certificate file, the play store won't let me upload the application, and
obviously I don't want to upload a new app.
Is there a way to force uninstall in order to update?
Thanks!
There's no killswitch to remotely force uninstalls (that'd be a security nightmare). What you can do is publish a fixed version on Google Play, and wait for users to upgrade.
I don't know if this can help you but i had the same problem. The solution for me is that i check the app version every time the user opens it and compare it with a version code stored on apache server (in a checkversion.php file).
If versions doesn't match, i show a not cancelable dialog that ask the user to go to market and download the update.
Here is an example (keep in mind that i use Volley library to handle connections):
public class UpdateManager {
private Activity ac;
private HashMap<String,String> params;
public UpdateManager(Activity ac) {
this.ac = ac;
}
public void checkForUpdates() {
Log.d("UpdateManager","checkForUpdates() - Started...");
params = new HashMap<String,String>();
params.put("request","checkforupdates");
try {
params.put("versioncode", String.valueOf(ac.getPackageManager().getPackageInfo(ac.getPackageName(), 0).versionCode));
} catch (NameNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (Helper.isInternetAvailable(ac)) { //this is a class i made to check internet connection availability
checkAppVersion();
} else { Log.d("UpdateManager","CheckForUpdates(): Impossible to update version due to lack of connection"); }
}
private void checkAppVersion() {
Log.d("UpdateManager","checkAppVersion() - Request started...");
JsonObjectRequest req = new JsonObjectRequest("http://yourserver/checkappversion.php", new JSONObject(params),
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
if (response != null && response.has("result")) {
try {
Log.d("UpdateManager","checkAppVersion() - Request finished - Response: "+response.getString("result"));
if (response.getString("result").matches("updaterequested")) { //Update requested. Show the relative dialog
Log.d("UpdateManager","Update requested");
askUserForUpdate();
}
else if (response.getString("result").matches("current")) { //Same version. Do nothing
Log.d("UpdateManager","Version is up to date");
}
else if (response.getString("result").matches("error")) { //You can return an error message if error occurred on server
Log.d("UpdateManager","checkappversion Error - "+response.getString("error"));
}
VolleyLog.v("Response:%n %s", response.toString(4));
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("UpdateManager","Volley Error - "+error.getMessage());
}
});
req.setRetryPolicy(new DefaultRetryPolicy(60000,0,DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
ConnectionController.getInstance().addToRequestQueue(req);
}
public void askUserForUpdate() {
final Dialog diag = new Dialog(ac);
diag.requestWindowFeature(Window.FEATURE_NO_TITLE);
diag.setContentView(R.layout.updatemanager_requestupdate_dialog);
diag.setCancelable(false);
diag.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
TextView t = (TextView)diag.findViewById(R.id.requestupdate_dialog_main_text);
ImageView im_ok = (ImageView)diag.findViewById(R.id.requestupdate_dialog_ok);
ImageView im_canc = (ImageView)diag.findViewById(R.id.requestupdate_dialog_canc);
t.setText(ac.getResources().getString(R.string.update_manager_askuserforupdate));
im_canc.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
diag.dismiss();
ac.finish();
}
});
im_ok.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("market://details?id="+ac.getPackageName()));
diag.dismiss();
ac.startActivity(intent);
ac.finish();
}
});
diag.show();
}
}
You can then use it when your main activity (or maybe login activity) starts like this:
UpdateManager updateManager = new UpdateManager(MainActivity.this); //i assume MainActicity as the calling activity
updateManager.checkForUpdates();
Obviously this has to be implemented into the application code so, the first time, you have to rely only on the user to manually upgrade it. But this can help if you have the same problem in the future.
This is an extract from my personal code so you have to rearrange it to your needings. Hope this helps someone.
Users should be able to go to Settings > Applications > Manage Applications and select the application to be removed. I've never seen a case where the application can't be removed this way, except in the case of built-in applications which require a rooted device to remove.