I'm developing an android application in Java where I need to pass the referer information to an URL. I'm getting the referrer information using Play Install Referrer Library.
Here is my code:
InstallReferrerClient referrerClient = InstallReferrerClient.newBuilder(this).build();
referrerClient.startConnection(new InstallReferrerStateListener() {
#Override
public void onInstallReferrerSetupFinished(int responseCode) {
switch (responseCode) {
case InstallReferrerClient.InstallReferrerResponse.OK:
try {
Log.v("TAG", "InstallReferrer conneceted");
ReferrerDetails response = referrerClient.getInstallReferrer();
System.out.println("referrerUrl ID: " + response);
referrerClient.endConnection();
} catch (RemoteException e) {
e.printStackTrace();
}
break;
case InstallReferrerClient.InstallReferrerResponse.FEATURE_NOT_SUPPORTED:
Log.w("TAG", "InstallReferrer not supported");
break;
case InstallReferrerClient.InstallReferrerResponse.SERVICE_UNAVAILABLE:
Log.w("TAG", "Unable to connect to the service");
break;
default:
Log.w("TAG", "responseCode not found.");
}
}
#Override
public void onInstallReferrerServiceDisconnected() {
// Try to restart the connection on the next request to
// Google Play by calling the startConnection() method.
}
});
Code is working fine and currently, the above snippet is inside my activity's onCreate method. which means it will start the new connection every time the user opens the activity.
In the library documentation, they have written that
Caution: The install referrer information will be available for 90
days and won't change unless the application is reinstalled. To avoid
unnecessary API calls in your app, you should invoke the API only once
during the first execution after install.
This is where I'm stuck, should I just call this thing when the application starts the first time?
If yes, I can store this referrer in the shared preference, but then how will I able to know that 90 days have been passed and I need to trigger that action again? Or it there something else that should I need to implement? Kindly help me with this issue.
Related
The requirement is to create a desktop notification which can register a click-event. I cannot use web-sockets or any browser notifications.
I am unable to use Tray-Icons and SystemTray because they cannot register Click-Events on DISPLAY MESSAGE. They can have click-events on the trayicon but not on the display message. The closest example - "When we register a click on a Skype message, it opens Skype for us"
Screenshot
On clicking the above Notification Skype chat opens-up. The same functionality is not supported with Tray-Icons. Either a work around it or a new approach will be do.
Hope I am clear thanks.
I used the following repository from github DorkBox.
Simply add maven dependency as instructed on the github link. However, I was unable to check how to change the UI for the notifications.
Notify.create()
.title(text)
.text(title)
.position(Pos.TOP_RIGHT)
.onAction( new ActionHandler<Notify>() {
#Override
public void handle(Notify value) {
if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
try {
Desktop.getDesktop().browse(new URI(targetUrl));
} catch (IOException e) {
e.printStackTrace();
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
}
})
.hideAfter(5000)
.shake(250, 5)
.darkStyle() // There are two default themes darkStyle() and default.
.showConfirm(); // You can use warnings and error as well.
Add the following code in your main block and you are good to go.
I have two app on Google Play. The old and new one. And I would like to use old auth token to the new app to be easier for users.
On the old app, the user has a popup to install the new app on Google Play.
I would like to pass the auth token in parameter to Google Play.
After new app has been installed, I would like to save the token in the new one app.
I tried to use Play Install Referrer Library but it didn't work.
The other way was to use SharedPreferences but MODE_WORLD_READABLE has been deprecated.
Old APP :
try {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=com.<PACKAGENAME>&token=pokpok&refresh_token=lolol"));
startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=com.<PACKAGENAME>?token=pokpok&refresh_token=lolol")));
}
New APP code :
private fun shouldGetTokenFromOldApp() {
mReferrerClient = InstallReferrerClient.newBuilder(this).build()
mReferrerClient.startConnection(object : InstallReferrerStateListener {
override fun onInstallReferrerSetupFinished(responseCode: Int) {
when (responseCode) {
InstallReferrerClient.InstallReferrerResponse.OK -> {
// Connection established
val response: ReferrerDetails = mReferrerClient.installReferrer
val url = "https://play.google.com/store?${response.installReferrer}"
Log.d("APP", "Token old app 1 : $url")
val uri: Uri = Uri.parse(url)
val token = uri.getQueryParameter("token")
val refreshToken = uri.getQueryParameter("refresh_token")
Log.d("APP", "Token old app 2 : $token - $refreshToken")
mReferrerClient.endConnection()
}
InstallReferrerClient.InstallReferrerResponse.FEATURE_NOT_SUPPORTED -> {
// API not available on the current Play Store app
}
InstallReferrerClient.InstallReferrerResponse.SERVICE_UNAVAILABLE -> {
// Connection could not be established
}
}
}
override fun onInstallReferrerServiceDisconnected() {
// Try to restart the connection on the next request to
// Google Play by calling the startConnection() method.
}
})
}
This sounds like a nice thing to do for users, but seems very dangerous. You are sending an Auth token - something which if someone has it could allow them to login as that user anywhere off through untrusted systems like world readable files or referral parameters in URLs.
If you really need to do this, I'd suggest using some form of inter-app RPC (IPC) to communicate the token after the app is installed. One option would be a binder to a service that supplies the auth.
I'm currently trying to integrate Facebook into my Android application. I've had no problems getting the app to connect and authenticate. But I'm having a little trouble understanding how I can handle data once the onCompleted(Response response) callback method is executed.
The method below works:
private void onSessionStateChange(Session session, SessionState state,
Exception exception) {
if (state.isOpened()) {
Log.i(TAG, "Logged in...");
new Request(session, "/me", null, HttpMethod.GET,
new Request.Callback() {
#Override
public void onCompleted(Response response) {
GraphObject graphObject = response.getGraphObject();
JSONObject data = graphObject.getInnerJSONObject();
Log.i(TAG, "My DETAILS: ");
try {
Log.i(TAG, "ID: " + data.getLong("id"));
Log.i(TAG, "Name: " + data.getString("name"));
Log.i(TAG, "Email: " + data.getString("email"));
Log.i(TAG,
"Gender: " + data.getString("gender"));
} catch (JSONException e) {
e.printStackTrace();
}
}
}).executeAsync();
} else if (state.isClosed()) {
Log.i(TAG, "Logged out...");
}
}
When I run my application, Facebook authenticates, the data is retrieved and successfully outputs to the Logcat window. However, I'm at a loss to understand how I can pass the JSONObject back to my fragment for further processing.
Most examples I've looked at online simply set the JSONObject content to views in the fragment, or even less helpful simply say /* Handle response here */ or something similar.
I have another similar method where I want to get a profile image url and download the image, but I can't get the url back to my fragment for further processing.
Should I do something like develop a runnable class that accepts a JSONObject as a parameter and start a separate thread from the onCompleted() method to process it the way I want?
My current goal is to get a list of the users friends who use my app and save their profile pictures for use within the app. Am I going about this the wrong way?
SO if I understand you properly, you are getting all data, you are able to parse the JSON but you are not able to pass the data to your other fragment? Why dont you write to a file, which can be accessible from anywhere?
Why do you want to "DOWNLOAD" the images, that will increase your processing time. Just use this URL: https://graph.facebook.com/"+uid.trim()+"/picture?type=normal Where uid is your users id. Use this in Conjunction with Universal Image Loader to asynchronously load your images in image view. You save your time - you save a headache of manually caching files or saving them on the SD.
But bro, the problem here is that Facebook will stop support to the API you are using by April of 2015. Start porting your app to use the latest facebook API; which however is not so useful in getting users information. Cheers and keep on coding :)
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.