Im trying to do this tutorial
But keep getting this error:
08-21 14:12:49.599: E/AndroidRuntime(714):
java.lang.NoClassDefFoundError:
com.akiraapps.LicenseCheck$MyLicenseCheckerCallback
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.provider.Settings.Secure;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.TextView;
import com.google.android.vending.licensing.AESObfuscator;
import com.google.android.vending.licensing.LicenseChecker;
import com.google.android.vending.licensing.LicenseCheckerCallback;
import com.google.android.vending.licensing.Policy;
import com.google.android.vending.licensing.ServerManagedPolicy;
public class LicenseCheck extends Activity {
private static final String BASE64_PUBLIC_KEY = "no";
private static final byte[] SALT = new byte[] { no};
private TextView mStatusText;
private Button mCheckLicenseButton;
private LicenseCheckerCallback mLicenseCheckerCallback;
private LicenseChecker mChecker;
// A handler on the UI thread.
private Handler mHandler;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.main);
mStatusText = (TextView) findViewById(R.id.status_text);
mCheckLicenseButton = (Button) findViewById(R.id.check_license_button);
mCheckLicenseButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
doCheck();
}
});
mHandler = new Handler();
// Try to use more data here. ANDROID_ID is a single point of attack.
String deviceId = Secure.getString(getContentResolver(), Secure.ANDROID_ID);
// Library calls this when it's done.
mLicenseCheckerCallback = new MyLicenseCheckerCallback();
// Construct the LicenseChecker with a policy.
mChecker = new LicenseChecker(
this, new ServerManagedPolicy(this,
new AESObfuscator(SALT, getPackageName(), deviceId)),
BASE64_PUBLIC_KEY);
doCheck();
}
protected Dialog onCreateDialog(int id) {
final boolean bRetry = id == 1;
return new AlertDialog.Builder(this)
.setTitle(R.string.unlicensed_dialog_title)
.setMessage(bRetry ? R.string.unlicensed_dialog_retry_body : R.string.unlicensed_dialog_body)
.setPositiveButton(bRetry ? R.string.retry_button : R.string.buy_button, new DialogInterface.OnClickListener() {
boolean mRetry = bRetry;
public void onClick(DialogInterface dialog, int which) {
if ( mRetry ) {
doCheck();
} else {
Intent marketIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(
"http://market.android.com/details?id=" + getPackageName()));
startActivity(marketIntent);
}
}
})
.setNegativeButton(R.string.quit_button, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
finish();
}
}).create();
}
private void doCheck() {
mCheckLicenseButton.setEnabled(false);
setProgressBarIndeterminateVisibility(true);
mStatusText.setText(R.string.checking_license);
mChecker.checkAccess(mLicenseCheckerCallback);
}
private void displayResult(final String result) {
mHandler.post(new Runnable() {
public void run() {
mStatusText.setText(result);
setProgressBarIndeterminateVisibility(false);
mCheckLicenseButton.setEnabled(true);
}
});
}
private void displayDialog(final boolean showRetry) {
mHandler.post(new Runnable() {
public void run() {
setProgressBarIndeterminateVisibility(false);
showDialog(showRetry ? 1 : 0);
mCheckLicenseButton.setEnabled(true);
}
});
}
private class MyLicenseCheckerCallback implements LicenseCheckerCallback {
public void allow(int policyReason) {
System.out.println("Allow");
if (isFinishing()) {
// Don't update UI if Activity is finishing.
return;
}
// Should allow user access.
displayResult(getString(R.string.allow));
}
public void dontAllow(int policyReason) {
System.out.println("dontAllow");
if (isFinishing()) {
// Don't update UI if Activity is finishing.
return;
}
displayResult(getString(R.string.dont_allow));
// Should not allow access. In most cases, the app should assume
// the user has access unless it encounters this. If it does,
// the app should inform the user of their unlicensed ways
// and then either shut down the app or limit the user to a
// restricted set of features.
// In this example, we show a dialog that takes the user to Market.
// If the reason for the lack of license is that the service is
// unavailable or there is another problem, we display a
// retry button on the dialog and a different message.
displayDialog(policyReason == Policy.RETRY);
}
public void applicationError(int errorCode) {
System.out.println("applicationError");
if (isFinishing()) {
// Don't update UI if Activity is finishing.
return;
}
// This is a polite way of saying the developer made a mistake
// while setting up or calling the license checker library.
// Please examine the error code and fix the error.
String result = String.format(getString(R.string.application_error), errorCode);
displayResult(result);
}
}
#Override
protected void onDestroy() {
super.onDestroy();
mChecker.onDestroy();
}
}
I follow the tutorial for setting up LVL as a library project and those imports seem to be ok.
Why do I get this error? Why can it not find the inner class? If I right click and say show definition it jumps to the inner class.
I had same problem.
Below steps solved the probelm
take standard library example
coppied the library.jar file from the library project into your libs folder
So this SO Answer is what fixed it
I created a folder called libs and coppied the library.jar file from the library project included in the licensing package downloaded with the manager
What I dont understand is per this answer this should have been done for me
As I am using ADT 20.0.3
Basically it comes down to an example that I downloaded directly from android and got stuck for a few hours trying to figure out what was wrong and this seems like this step should have been in the readme/help docs OR Im doing something wrong.
If you know why this is the answer and how to do it better please answer and Ill change the answer to yours.
I had the exact same exception and none of the above recommendations worked for me.
However I got mine working by ensuring that your LVL project is a library project (right click project -> properties -> android and tick the "Is Libary" checkbo).
To include this in your application project remove any other references to this and apply the changes. Then if not already there navigate to (right click application project --> properties --> android) and in the library section click Add and select your LVL project. Apply Changes. Ok and clean project.
Hope this helps someone.
Related
I am developing an android app to retrieve data through php,mysql,json from a database. I need to create a service or any way to call getData() method every 10 minutes. I tried placing these 2 methods in a broadcast receiver and used alarm manager to repeat every 10 mins but it didn't run properly, it worked only for Toast and Log.d (simple operations). Is there an simple approach to achieve what I want ? I did search a lot, but couldn't find a clear answer
//METHOD 1
private void getData() {
loading = ProgressDialog.show(this,"Please wait...","Fetching...",false,false);
String url = Config.DATA_URL;
StringRequest stringRequest = new StringRequest(url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
loading.dismiss();
showJSON(response);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(MainActivity.this,error.getMessage().toString(),Toast.LENGTH_LONG).show();
}
});
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
// METHOD 2
private void showJSON(String response){
String id="";
String time="";
String value = "";
try {
JSONObject jsonObject = new JSONObject(response);
JSONArray result = jsonObject.getJSONArray(Config.JSON_ARRAY);
for (int i = 0; i < result.length(); i++) {
JSONObject tempData = result.getJSONObject(i);
id = tempData.getString(Config.KEY_NAME);
time = tempData.getString(Config.KEY_ADDRESS);
value = tempData.getString(Config.KEY_VC);
String data = "Id:\t"+id+", Time:\t" +time+ ", Value:\t"+ value;
all += data+"\n";
}
}
catch (JSONException e) {
e.printStackTrace();
}
textViewResult.setText(all);
}
Your way of using a broadcast receiver (BR) and an Alarm manager sounds like a good approach and I'm not sure exactly what problem you encountered. Could you tell us more?
Without all the details I'd say that a potential problem is that a Broadcast receiver is normally executed in the UI thread of Android and that does not for example allow you to perform network access and it must finish within X seconds.
1) You don't have the right permissions to access internet? From what I remember the log of this can be easy to miss.
2) Either you can request the BR to run the a background thread, I know you can do it, not tried myself.
3) You can start another thread. As you seen to update the UI you should probably use an Async Task for this. So you can do the network in a background thread and then you you get a call in the UI thread with the new data. (This would probably be the option to go to)
Side note: for parsing json, I'd recommend you to look at Gson. It's a library from google that makes the parsin of Json much simpler. https://github.com/google/gson
import com.google.android.gms.gcm.GcmTaskService;
import com.google.android.gms.gcm.TaskParams;
import android.content.Context;
import android.content.SharedPreferences;
import android.location.Address;
import android.location.Geocoder;
import android.net.ConnectivityManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.widget.Toast;
import com.google.android.gms.gcm.GcmNetworkManager;
import com.google.android.gms.gcm.OneoffTask;
import com.google.android.gms.gcm.PeriodicTask;
import com.google.android.gms.gcm.Task;
import com.rcsplcms.ess.Constant;
import com.rcsplcms.ess.GPSTracker;
import com.rcsplcms.ess.R;
import com.rcsplcms.ess.application.ESSApplication;
import com.rcsplcms.ess.util.AppLog;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapPrimitive;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import java.util.List;
import java.util.Locale;
/**
* Created by MAYURKUMAR TERAIYA on 20-09-2017.
*/
public class GCMServiceTracking extends GcmTaskService {
private static final String TAG = GCMServiceTracking.class.getSimpleName();
public static final String GCM_ONEOFF_TAG = "oneoff|[0,0]";
public static final String GCM_REPEAT_TAG = "repeat|[7200,1800]";
#Override
public void onInitializeTasks() {
//called when app is updated to a new version, reinstalled etc.
//you have to schedule your repeating tasks again
super.onInitializeTasks();
}
#Override
public int onRunTask(TaskParams taskParams) {
//do some stuff (mostly network) - executed in background thread (async)
//Toast.makeText(getApplicationContext(), "Service Executed",
Toast.LENGTH_SHORT).show();
//obtain your data
Bundle extras = taskParams.getExtras();
Handler h = new Handler(getMainLooper());
Log.v(TAG, "onRunTask");
if (taskParams.getTag().equals(GCM_ONEOFF_TAG)) {
h.post(new Runnable() {
#Override
public void run() {
//Toast.makeText(GCMServiceTracking.this, "ONEOFF executed",
Toast.LENGTH_SHORT).show();
}
});
} else if (taskParams.getTag().equals(GCM_REPEAT_TAG)) {
h.post(new Runnable() {
#Override
public void run() {
//Toast.makeText(GCMServiceTracking.this, "REPEATING executed", Toast.LENGTH_SHORT).show();
gpsTracker = new GPSTracker(GCMServiceTracking.this);
Toast.makeText(getApplicationContext(), "Data Syncing.", Toast.LENGTH_SHORT).show();
}
});
}
return GcmNetworkManager.RESULT_SUCCESS;
}
public static void scheduleOneOff(Context context) {
//in this method, single OneOff task is scheduled (the target service
that will be called is MyTaskService.class)
Bundle data = new Bundle();
data.putString("some key", "some budle data");
try {
OneoffTask oneoff = new OneoffTask.Builder()
//specify target service - must extend GcmTaskService
.setService(GCMServiceTracking.class)
//tag that is unique to this task (can be used to cancel task)
.setTag(GCM_ONEOFF_TAG)
//executed between 0 - 10s from now
.setExecutionWindow(10, 10)
//set required network state, this line is optional
.setRequiredNetwork(Task.NETWORK_STATE_ANY)
//request that charging must be connected, this line is optional
.setRequiresCharging(false)
//set some data we want to pass to our task
.setExtras(data)
//if another task with same tag is already scheduled, replace it with this task
.setUpdateCurrent(true)
.build();
GcmNetworkManager.getInstance(context).schedule(oneoff);
Log.v(TAG, "oneoff task scheduled");
} catch (Exception e) {
e.printStackTrace();
}
}
public static void scheduleRepeat(Context context) {
//in this method, single Repeating task is scheduled (the target service that will be called is MyTaskService.class)
try {
PeriodicTask periodic = new PeriodicTask.Builder()
//specify target service - must extend GcmTaskService
.setService(GCMServiceTracking.class)
//repeat every 60 seconds
.setPeriod(300)
//specify how much earlier the task can be executed (in seconds)
.setFlex(30)
//tag that is unique to this task (can be used to cancel task)
.setTag(GCM_REPEAT_TAG)
//whether the task persists after device reboot
.setPersisted(true)
//if another task with same tag is already scheduled, replace it with this task
.setUpdateCurrent(true)
//set required network state, this line is optional
.setRequiredNetwork(Task.NETWORK_STATE_ANY)
//request that charging must be connected, this line is optional
.setRequiresCharging(false)
.build();
GcmNetworkManager.getInstance(context).schedule(periodic);
Log.v(TAG, "repeating task scheduled");
} catch (Exception e) {
Log.e(TAG, "scheduling failed");
e.printStackTrace();
}
}
public static void cancelOneOff(Context context) {
GcmNetworkManager
.getInstance(context)
.cancelTask(GCM_ONEOFF_TAG, GCMServiceTracking.class);
}
public static void cancelRepeat(Context context) {
GcmNetworkManager
.getInstance(context)
.cancelTask(GCM_REPEAT_TAG, GCMServiceTracking.class);
}
public static void cancelAll(Context context) {
GcmNetworkManager
.getInstance(context)
.cancelAllTasks(GCMServiceTracking.class);
}
}
// CODE FOR START BACKGROUND TASK
GoogleApiAvailability api = GoogleApiAvailability.getInstance();
Int errorCheck = api.isGooglePlayServicesAvailable(LoginActivity.this);
if(errorCheck == ConnectionResult.SUCCESS) {
//google play services available, hooray
} else if(api.isUserResolvableError(errorCheck)) {
//GPS_REQUEST_CODE = 1000, and is used in onActivityResult
api.showErrorDialogFragment(LoginActivity.this, errorCheck, GPS_REQUEST_CODE);
//stop our activity initialization code
return;
} else {
//GPS not available, user cannot resolve this error
//todo: somehow inform user or fallback to different
method
//stop our activity initialization code
return;
}
GCMServiceTracking.scheduleRepeat(LoginActivity.this);
GRADLE FILE
compile 'com.google.android.gms:play-services:8.3.0'
MENIFEST FILE
<service
android:name=".services.GCMServiceTracking"
android:exported="true"
android:permission="com.google.android.gms.permission.BIND_NETWORK_TASK_SERVICE">
<intent-filter>
<action android:name="com.google.android.gms.gcm.ACTION_TASK_READY" />
</intent-filter>
</service>
I'm trying to take control over the Play/Pause html DOM elements (in a browser open in a pc) from an android device.
In the html page (in Google Chrome browser) there's a <video> tag so I can control it like this:
//js code
document.querySelector("video").play();
document.querySelector("video").pause();
But I want that to run from an android device so I'm using GCM.
I read here and got some insight but I still have some questions.
First, since I'm writing in eclipse, and it sees no document variable, it produces an error. So how can eclipse recognize that element in the html page so I can compile and install the apk on the device?
Where do I specify the page url I want to communicate with? (send play/pause commands)
To run js inside java I'm using Rhino. I looked through the examples in the documentation but I'm still not sure if a #JSFunction annotation is enough to declare a js function.
Here's my code:
import com.alaa.chromote.util.SystemUiHider;
import com.google.android.gcm.GCMRegistrar;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.Toast;
import android.view.View.OnClickListener;
import org.mozilla.javascript.*;
import org.mozilla.javascript.annotations.*;
public class MainApplication extends Activity {
private final static String GCM_SENDER_ID = "484514826047";
private static final String LOG_TAG = "GetAClue::GCMIntentService";
private Button playButton;
private Button pauseButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_application);
playButton = (Button) findViewById(R.id.PlayButton);
pauseButton = (Button) findViewById(R.id.PauseButton);
playButton.setVisibility(View.INVISIBLE);
pauseButton.setVisibility(View.VISIBLE);
//connect to gcm
GCMRegistrar.checkDevice( this );
GCMRegistrar.checkManifest( this );
final String regId = GCMRegistrar.getRegistrationId( this );
if( regId.equals( "" ) ) {
GCMRegistrar.register( this, GCM_SENDER_ID );
}
else {
Log.v( LOG_TAG, "Already registered" );
}
Context.enter(); //start Rhino
setupListeners();
}
#JSFunction
public void play() { document.querySelector("video").play(); }
#JSFunction
public void pause() { document.querySelector("video").pause(); }
private void setupListeners()
{
playButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
play();
}
});
pauseButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
pause();
}
});
}
#Override
protected void onStop() {
Context.exit(); //stop Rhino
super.onStop();
}
}
How do I continue from here?
First, since I'm writing in eclipse, and it sees no document variable, it produces an error. So how can eclipse recognize that element in the html page so I can compile and install the apk on the device?
answ: On your android device you just pass a message to the chrome browser. A.k. an action variable that is set to play or stop. You chrome app will then pick up the message and act accordingly. Also you can send the url as an variable in the message if you want to be able to play different urls.
Where do I specify the page url I want to communicate with? (send play/pause commands)?
answ: Do you already created the chrome app you want and verified it works? It should check with a google cloud server for messages. That server keeps track of the url for you.
To run js inside java I'm using Rhino. I looked through the examples in the documentation but I'm still not sure if a #JSFunction annotation is enough to declare a js function.?
answ: It seems you are misunderstanding the part what the android app does (sending the play action) and what the chrome browser does (actually playing the movie)
I hope my answer has helped a little, feedback is appreciated :)
I'm checking avalibility of google play services on device. I do it with these code:
final int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (resultCode != ConnectionResult.SUCCESS) {
final DialogInterface.OnCancelListener cancelListener = new DialogInterface.OnCancelListener() {
#Override
public void onCancel(final DialogInterface dialog) {
finish();
}
};
final Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(
resultCode, this, GOOGLE_PLAY_SERVICES_REQUEST_CODE, cancelListener
);
errorDialog.show();
}
I get resultCode = 2 (it's mean that Google Play Services needs to update). Dialog is shown, but instead of text, I get paths to layout.
It's looks like there are some interference of resource in app and resource in PlaYServices lib. But how it's possible and how to avoid id?
Since the accepted answer is somewhat unclear, I'll leave a signpost with my conclusions (mostly extracted from the comments on the question) which I believe are correct.
Short version: It seems that resource ids were incorrectly generated for this app.
It's obvious that the Google Play Services dialog intended to show strings in those places. The getErrorDialog() method is implemented like this (obfuscated, but the meaning can still be understood):
...
case 1:
return localBuilder.setTitle(R.string.common_google_play_services_install_title).create();
case 3:
return localBuilder.setTitle(R.string.common_google_play_services_enable_title).create();
case 2:
return localBuilder.setTitle(R.string.common_google_play_services_update_title).create();
...
Also, mistakenly doing something like getResources().getString(R.layout.my_layout) will return a string with the name of the original resource file ("res/layout/my_layout.xml").
So, we can conclude that, for some reason, the value of the Play Services Library resource, say, com.google.android.gms.R.string.common_google_play_services_install_title is actually the same as for the resource R.layout.dialog_share in the application project.
This probably stems for an incorrect build process, or an incorrect usage of the Google Play Services library (for example, including its jar directly, without the corresponding library process).
I have tested the code with google play service library version 4452000(use version >= 4452000). The code is as follows:
public class MainActivity extends Activity{
ProgressBar pBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (resultCode != ConnectionResult.SUCCESS) {
final DialogInterface.OnCancelListener cancelListener = new DialogInterface.OnCancelListener() {
#Override
public void onCancel(final DialogInterface dialog) {
finish();
}
};
final Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(
resultCode, this, 10, cancelListener
);
errorDialog.show();
}
}
}
Check your version of google play services and update if needed.
Here's the class I've been working on to check google play. It's not in production later this summer it will be so let me know with a comment if you have problems. It works tested on zten9120 and HTC EVO. The flow is like this. If static method isGooglePlay(context) returns false. Initialize the class and call the non static isgoogleplay() which will present the dialog to the user if googleplay services is not installed. The oncofigurationchange method handles when the device is rotated. onstop sets the class to null.
Modify three events in your activity.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (!MyGooglePlay.isGooglePlay(getApplicationContext())) {
myGP = new MyGooglePlay(this);
myGP.isGooglePlay();
}
#Override
public void onStop() {
super.onStop();
myGP = null;
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (myGP != null) {
if (myGP.errorFragment.isVisible()) {
myGP.errorFragment.dismissAllowingStateLoss();
}
}
}
Here's the code which I keep in separate class
package com.gosylvester.bestrides.util;
import android.app.Dialog;
import android.content.Context;
import android.content.IntentSender;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.ActionBarActivity;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
public class MyGooglePlay {
private static final int CONNECTION_FAILURE_RESOLUTION_REQUEST = 31502;
private ActionBarActivity activity;
private FragmentManager fragManager;
public MyGooglePlay(ActionBarActivity activity) {
this.activity = activity;
this.fragManager = activity.getSupportFragmentManager();
}
public static boolean isGooglePlay(Context context) {
return (GooglePlayServicesUtil.isGooglePlayServicesAvailable(context) == ConnectionResult.SUCCESS);
}
public boolean isGooglePlay() {
if (isGooglePlay(activity)) {
return true;
} else {
return checkGooglePlay();
}
}
private static final String DIALOG_ERROR = "dialog_error";
public ErrorDialogFragment errorFragment;
private boolean checkGooglePlay() {
int mIsGooglePlayServicesAvailable = GooglePlayServicesUtil
.isGooglePlayServicesAvailable(activity);
switch (mIsGooglePlayServicesAvailable) {
case ConnectionResult.SUCCESS:
return true;
default:
Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(
mIsGooglePlayServicesAvailable, activity,
CONNECTION_FAILURE_RESOLUTION_REQUEST);
// If Google Play services can provide an error dialog
if (errorDialog != null) {
// Create a new DialogFragment for the error dialog
errorFragment = ErrorDialogFragment.newInstance();
// Set the dialog in the DialogFragment
errorFragment.setDialog(errorDialog);
// Show the error dialog in the DialogFragment
errorFragment.show(fragManager, "LocationUpdates");
}
// case ConnectionResult.SERVICE_MISSING:
// case ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED:
// case ConnectionResult.SERVICE_DISABLED:
// case ConnectionResult.SERVICE_INVALID:
// case ConnectionResult.DATE_INVALID:
}
return false;
}
public void dismissMe() {
DialogFragment frag = (DialogFragment) fragManager
.findFragmentByTag("LocationUpdates");
if (frag != null) {
frag.dismissAllowingStateLoss();
}
}
public static class ErrorDialogFragment extends DialogFragment {
// Global field to contain the error dialog
private Dialog mDialog;
static ErrorDialogFragment newInstance() {
ErrorDialogFragment d = new ErrorDialogFragment();
return d;
}
// Default constructor. Sets the dialog field to null
public ErrorDialogFragment() {
super();
mDialog = null;
}
// Set the dialog to display
public void setDialog(Dialog dialog) {
mDialog = dialog;
}
public void onPause(){
super.onPause();
this.dismissAllowingStateLoss();
}
// Return a Dialog to the DialogFragment.
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return mDialog;
}
}
public void onConnectionFailed(ConnectionResult connectionResult) {
/*
* Google Play services can resolve some errors it detects. If the error
* has a resolution, try sending an Intent to start a Google Play
* services activity that can resolve error.
*/
if (connectionResult.hasResolution()) {
try {
// Start an Activity that tries to resolve the error
connectionResult.startResolutionForResult(activity,
CONNECTION_FAILURE_RESOLUTION_REQUEST);
/*
* Thrown if Google Play services canceled the original
* PendingIntent
*/
} catch (IntentSender.SendIntentException e) {
// Log the error
e.printStackTrace();
}
} else {
/*
* If no resolution is available, display a dialog to the user with
* the error.
*/
showErrorDialog(connectionResult.getErrorCode(), activity);
}
}
/* Creates a dialog for an error message */
private void showErrorDialog(int errorCode, ActionBarActivity activity) {
// Create a fragment for the error dialog
ErrorDialogFragment dialogFragment = new ErrorDialogFragment();
// Pass the error that should be displayed
Bundle args = new Bundle();
args.putInt(DIALOG_ERROR, errorCode);
dialogFragment.setArguments(args);
dialogFragment
.show(activity.getSupportFragmentManager(), "errordialog");
}
}
Good Luck with getting google play services installed.
public static boolean isGooglePlayServiceAvailable(Context context) {
boolean isAvailable = false;
int result = GooglePlayServicesUtil
.isGooglePlayServicesAvailable(context);
if (result == ConnectionResult.SUCCESS) {
Log.d(TAG, "Play Service Available");
isAvailable = true;
} else {
Log.d(TAG, "Play Service Not Available");
if (GooglePlayServicesUtil.isUserRecoverableError(result)) {
GooglePlayServicesUtil.getErrorDialog(result,
(Activity) context, PLAY_SERVICES_RESOLUTION_REQUEST)
.show();
} else {
Log.d(TAG, "Play Service Not Available");
GooglePlayServicesUtil.getErrorDialog(result,
(Activity) context, PLAY_SERVICES_RESOLUTION_REQUEST)
.show();
}
}
return isAvailable;
}
Updated answer : (as per GooglePlayServicesUtil.getErrorDialog is null)
If Google Play Services is not installed on the device, you may not be able to use the error dialog.
As per Rahim's comment in the above, you should only use the dialog if you have an "isUserRecoverableError" (his code):
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (status != ConnectionResult.SUCCESS) {
if (GooglePlayServicesUtil.isUserRecoverableError(status)) {
GooglePlayServicesUtil.getErrorDialog(status, this,
REQUEST_CODE_RECOVER_PLAY_SERVICES).show();
} else {
Toast.makeText(this, "This device is not supported.", Toast.LENGTH_LONG).show();
finish();
}
}
UPDATE - (from http://www.riskcompletefailure.com/2013/03/common-problems-with-google-sign-in-on.html)
One additional bug that surfaced quite a lot around the release of the latest version of Google Play Services was the onConnectionFailed method being called with a ConnectionResult which does not have a resolution, and has an error code of ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED.
As you might guess from the name, this indicates that the version of Google Play Services on the device is too low. Normally new versions will be updated automatically, but there is always a time delay in the roll out, so it is quite possible to get this error as updates are released.
You can handle this in the onConnectionFailed by calling getErrorDialog on GooglePlayServicesUtil, but the best way is to actually check whether Google Play Services is installed and up to date before even trying to connect. You can see a snippet of how to do this in the documentation.
So this is suggesting that this error (as you yourself say) should be recoverable, although note the clause that I have made bold. I am not convinced that this dialog would always be usable. Common sense suggests to me that this might depend on the version from which you were upgrading. So I recommend that you explicitly check that the error is marked as recoverable. If it is marked as recoverable then this looks like a bug in Google Play Services.
I found solution. I don't undertand why it's happening, but there is a solution.
I've built my project with maven and include a google play services framework as android library project.
Today, I've migrated to gradle and include dependecy go GPS with gradle and it solved my problem.
Iam making an android app which will authenticate a user into an active directory. Currently, I have followed a tutorial on http://www.windowsazure.com/en-us/documentation/articles/mobile-services-android-get-started-users/.
I only need to authenticate a user at this point. So I have done the following:-
import com.microsoft.windowsazure.mobileservices.MobileServiceApplication;
import com.microsoft.windowsazure.mobileservices.MobileServiceAuthenticationProvider;
import com.microsoft.windowsazure.mobileservices.MobileServiceClient;
import com.microsoft.windowsazure.mobileservices.MobileServiceUser;
import com.microsoft.windowsazure.mobileservices.ServiceFilterResponse;
import com.microsoft.windowsazure.mobileservices.UserAuthenticationCallback;
public static MobileServiceClient mobileServiceClient;
public MobileServiceUser _user;
MobileServiceClient mCLient;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
web = (WebView)findViewById(R.id.webSignin);
web.getSettings().setJavaScriptEnabled(true);
web.loadUrl("https://login.microsoftonline.com/login.srf?wa=wsignin1%2E0&rpsnv=2&ct=1390811289&rver=6%2E1%2E6206%2E0&wp=MBI&wreply=https%3A%2F%2Fwww7679%2Esharepoint%2Ecom%2F%5Flayouts%2F15%2Flanding%2Easpx%3FSource%3Dhttps%253A%252F%252Fzevenseascom%252D11%252Esharepoint%252Eemea%252Emicrosoftonline%252Ecom%252F%255Fforms%252Fdefault%252Easpx&lc=16393&id=500046&guests=1");
authenticate();
}
private void authenticate()
{
// TODO Auto-generated method stub
mCLient.login(MobileServiceAuthenticationProvider.Google, new UserAuthenticationCallback()
{
#Override
public void onCompleted(MobileServiceUser user, Exception exception,
ServiceFilterResponse response)
{
// TODO Auto-generated method stub
if(exception == null)
{
createAndShowDialog(String.format("You are now logged in - %1$2s", user.getUserId()),"Success");
Intent myIntent = new Intent(MainActivity.this, Directory.class);
startActivity(myIntent);
}
else
{
createAndShowDialog("You must log in. Login Required", "Error");
}
}
});
}
But i get the following error:-
java.lang.NoClassDefFoundError: com.microsoft.windowsazure.mobileservices.MobileServiceAuthenticationProvider
01-28 10:34:04.732: E/AndroidRuntime(2150): at com.example.activedirectory.MainActivity.authenticate(MainActivity.java:68)
Any help is appreciated
Please init for MobileServiceClient mCLient; You just declare, not init. May be it is
mClient = new MobileServiceClient(...);
And with error:
-01-28 11:56:50.974: E/AndroidRuntime(6793):
java.lang.NoClassDefFoundError: com.google.gson.GsonBuilder 01-28 11:56:50.974: E/AndroidRuntime(6793): at com.microsoft.windowsazure.mobileservices.MobileServiceClient.createMobileServiceGsonBuilder(MobileServiceClient.java:136) 01-28 11:56:50.974:
E/AndroidRuntime(6793): at com.microsoft.windowsazure.mobileservices.MobileServiceClient.<init>(MobileServiceClient.java:187)
just add library: GSON
Have you tried this solution.
Project Properties>Java Build Path>Order and Import tab and check the libraries you are using.
It seems that ADT update 22, you have to do this manually: Libraries do not get added to APK anymore after upgrade to ADT 22.
FATAL EXCEPTION: Thread-5195
java.lang.NullPointerException: src == null
at java.lang.System.arraycopy(Native Method)
at com.paypal.android.a.g.a(Unknown Source)
at com.paypal.android.a.h.c(Unknown Source)
at com.paypal.android.MEP.PayPal.setLanguage(Unknown Source)
at com.paypal.android.MEP.PayPal.initWithAppID(Unknown Source)
at com.lonfun.pets.UnityPayMenuActivity.initLibrary(UnityPayMenuActivity.java:256)
at com.lonfun.pets.UnityPayMenuActivity.access$2(UnityPayMenuActivity.java:249)
at com.lonfun.pets.UnityPayMenuActivity$2$1.run(UnityPayMenuActivity.java:175)
I just use android to open paypal, everything is ok, but if I call from unity, this is happened!
this is my java code:
package com.paypal.androidpets;
import android.content.Context;
import android.os.Handler;
import com.lonfun.pets.UnityPayMenuActivity;
import com.paypal.android.MEP.PayPal;
import com.paypal.android.MEP.PayPalActivity;
public class PaypalTool {
Context context;
PayPal pp;
private static final int server = PayPal.ENV_SANDBOX;
// The ID of your application that you received from PayPal
private static final String appID = "APP-80W284485P519543T";
public PaypalTool(Context context) {
this.context=context;
}
public void initLibrary(final Handler handler)
{
new Thread() {
public void run() {
PayPalActivity._paypal = null;
pp = PayPal.getInstance();
// If the library is already initialized, then we don't need to initialize it again.
if(pp == null) {
// pp = PayPal.initWithAppID(context, "", PayPal.ENV_NONE);
pp = PayPal.initWithAppID(context, appID, server);
pp.setShippingEnabled(false);
}
if (PayPal.getInstance().isLibraryInitialized()) {
handler.sendEmptyMessage(0);
}
else {
handler.sendEmptyMessage(1);
}
}
}.start();
}
}
has anybody solve this problem,,please help me, thank you!
using UnityEngine;
using System.Collections;
public class PayMoneyHandler : MonoBehaviour
{
#if UNITY_ANDROID
static AndroidJavaClass payPluginClass;
static AndroidJavaClass unityPlayer;
static AndroidJavaObject currActivity;
#endif
public static void Pay(string productID)
{
#if UNITY_ANDROID
AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
jo.Call("StartActivity0",
"com.peten.tier2",
"EGAHCNJDEJBWBIBWEXIKDEGLJECOAD.Mac",
"Dog",
"AndDogCn",
"http://42.121.94.123/TradeWeb/AlipayTrade.aspx",
"http://58.246.188.238/TradeWeb/PaypalTrade.aspx"
);
#endif
}
}
using UnityEngine;
using System.Collections;
public class TestForPaypal : MonoBehaviour {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
public void OnClick(){
Debug.Log("Test For Paypal!");
PayMoneyHandler.Pay("test1");
}
}
public void StartActivity0(final String name,final String PlayerName,final String GameID,final String ZoneID,final String payUrl,final String paypalUrl)
{
this.runOnUiThread(new Runnable() {
#Override
public void run() {
Log.i("Order", "name:"+name+"PlayerName:"+PlayerName+"GameID:"+GameID+"ZoneID:"+ZoneID+"payUrl:"+payUrl+"paypalUrl:"+paypalUrl);
Intent payintent=new Intent(mContext,UnityPayMenuActivity.class);
payintent.putExtra("name",name);
payintent.putExtra("PlayerName",PlayerName);
payintent.putExtra("GameID",GameID);
payintent.putExtra("ZoneID",ZoneID);
payintent.putExtra("payUrl",payUrl);
payintent.putExtra("paypalUrl",paypalUrl);
Unity3DMainActiviy.this.startActivity(payintent);
}
});
}
I think you didnot enter the appID and the server detail.
Below is the working code which i have implement and It works fine for me.
I have implement Pay on button click which extends the runnable
Check_out.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (_paypalLibraryInit) {
showPayPalButton();
//Toast.makeText(Android_PP_Test1Activity.this, captions[position], Toast.LENGTH_SHORT).show();
}
else {
// Display a progress dialog to the user and start checking for when
// the initialization is completed
Thread initThread = new Thread(initLibraryRunnable);
initThread.start();
_progressDialog = new ProgressDialog(Recharge.this);
_progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
_progressDialog.setMessage("Loading PayPal Payment Library");
_progressDialog.setCancelable(false);
_progressDialog.show();
_progressDialogRunning = true;
Thread newThread = new Thread(checkforPayPalInitRunnable);
newThread.start();
//Toast.makeText(Android_PP_Test1Activity.this, "Picasso Paintings", Toast.LENGTH_SHORT).show();
}
}
});
This button call this runnable method
//This lets us run the initLibrary function
final Runnable initLibraryRunnable = new Runnable() {
public void run() {
initLibrary();
}
};
and this method is responsible to initiate the initLibrary.
/** init method **/
public void initLibrary() {
PayPal pp = PayPal.getInstance();
if (pp == null) {
// This is the main initialization call that takes in your Context,
// the Application ID, and the server you would like to connect to.
pp=PayPal.initWithAppID(this,"APP80W284485P519543T",PayPal.ENV_SANDBOX);
// -- These are required settings.
pp.setLanguage("en_US"); // Sets the language for the library.
// --
// -- These are a few of the optional settings.
// Sets the fees payer. If there are fees for the transaction, this
// person will pay for them. Possible values are FEEPAYER_SENDER,
// FEEPAYER_PRIMARYRECEIVER, FEEPAYER_EACHRECEIVER, and
// FEEPAYER_SECONDARYONLY.
pp.setFeesPayer(PayPal.FEEPAYER_EACHRECEIVER);
// Set to true if the transaction will require shipping.
pp.setShippingEnabled(true);
// Dynamic Amount Calculation allows you to set tax and shipping
// amounts based on the user's shipping address. Shipping must be
// enabled for Dynamic Amount Calculation. This also requires you to
// create a class that implements PaymentAdjuster and Serializable.
pp.setDynamicAmountCalculationEnabled(false);
// --
}
}
Hope It helps...
The problem is when unity generates the apk file. I have compared one apk i made miself with PayPal integration only compiling with eclipse and other compiling with Unity.
Lets say the apk i made only with eclipse is called "PayPalOnlyEclipse.apk" and the one made with unity "PayPalWithUnity.apk"; y renamed them to "PayPalOnlyEclipse.zip" and "PayPalWithUnity.zip", then open both with WinRar to compare them.
I found that PayPalOnlyEclipse had one folder that PayPalWithUnity didn't, the folder is "com\paypal\android\utils\data". So I decompressed that folder and then added it to PayPalWithUnity. Then erase the META-INF folder (the signing), then close the "PayPalWithUnity.zip" and rename it like it was before ("PayPalWithUnity.apk").
Then I used the command for signing the apk file:
jarsigner -verbose -sigalg MD5withRSA -digestalg SHA1 -keystore my.keystore PayPalWithUnity.apk user
Finally I used the command for zipalign:
zipalign -v 4 PayPalWithUnity.apk PayPalWithUnity2.apk
that command generates PayPalWithUnity2.apk and that is the apk file you have to install in your phone.
Hope it helps, and sorry for my english.
Check if you have included the PaypalActivity on manifest file. Like this:
<activity android:name="com.paypal.android.MEP.PayPalActivity"
android:configChanges="keyboardHidden|orientation" />
If you have it and it doesnt work yet, include the library on the build path (Properties>>Java Buid Path>>Libraries>>Add JARs) and add it on the "order and export" tab (Properties>>Java Buid Path>>Order and Export).