在编译我的Android应用程序期间,我遇到了一个google +登录测试应用程序,出现了以下错误(请参阅logcat消息)。我提供了清单和gradle配置文件,以及Java中的app源以供参考。
任何人都可以帮助我理解这个问题吗?
logcat消息:
I/dalvikvm﹕ Could not find method android.app.Notification$Builder.setLocalOnly, referenced from method com.google.android.gms.common.GooglePlayServicesUtil.zza
W/dalvikvm﹕ VFY: unable to resolve virtual method 196: Landroid/app/Notification$Builder;.setLocalOnly (Z)Landroid/app/Notification$Builder;
D/dalvikvm﹕ VFY: replacing opcode 0x6e at 0x00c2
I/dalvikvm﹕ DexOpt: access denied from Lcom/google/android/gms/common/GooglePlayServicesUtil; to field Landroid/app/Notification;.extras
W/dalvikvm﹕ VFY: unable to resolve instance field 13
D/dalvikvm﹕ VFY: replacing opcode 0x54 at 0x00e1
E/dalvikvm﹕ Could not find class 'android.app.AppOpsManager', referenced from method com.google.android.gms.common.GooglePlayServicesUtil.zza
W/dalvikvm﹕ VFY: unable to resolve check-cast 19 (Landroid/app/AppOpsManager;) in Lcom/google/android/gms/common/GooglePlayServicesUtil;
重现的步骤:
的manifest.xml
<application android:name="android.support.multidex.MultiDexApplication"
......
<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version"/>
......
/>
gradle.build
apply plugin: 'com.android.application'
android {
compileSdkVersion 22
buildToolsVersion "22.0.1"
defaultConfig {
applicationId "com.test.app"
minSdkVersion 16
targetSdkVersion 22
versionCode 1
versionName "1.0"
//https://developer.android.com/tools/building/multidex.html
//http://stackoverflow.com/questions/29756188/java-finished-with-non-zero-exit-value-2-android-gradle
//http://stackoverflow.com/questions/29033800/noclassdeffounderror-below-sdk-21
multiDexEnabled true
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
packagingOptions {
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/NOTICE'
exclude 'META-INF/LICENSE'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/ASL2.0'
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
//http://stackoverflow.com/questions/32205938/java-lang-noclassdeffounderror-android-support-v4-view-layoutinflatercompathc-i
compile 'com.android.support:multidex:1.0.0'
//Google+ login
compile 'com.google.android.gms:play-services:7.5.0'
compile 'com.android.support:appcompat-v7:22.2.1'
//ZXing Library
compile 'com.journeyapps:zxing-android-embedded:3.0.2@aar'
compile 'com.google.zxing:core:3.2.0'
//Joda-time
compile 'net.danlew:android.joda:2.8.2'
//
compile 'com.android.support:recyclerview-v7:22.0.+'
compile 'com.android.support:cardview-v7:22.0.+'
compile 'org.apache.httpcomponents:httpmime:4.2.3'
compile 'com.kakao.sdk:kakaolink:1.1.2'
compile 'com.kakao.sdk:usermgmt:1.1.2'
//glide
compile 'com.github.bumptech.glide:glide:3.6.1'
}
Login.java活动
public class Login extends TroubleoActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener{
final static private int RC_SIGN_IN = 0;
final static private String TAG = "Login";
private GoogleApiClient mGoogleApiClient;
private ConnectionResult mConnectionResult;
private boolean mIntentInProgress;
private boolean mSignInClicked;
private int PROFILE_PIC_SIZE = 400;
private SignInButton btnSignIn;
private ImageView imgProfilePic;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login);
btnSignIn = (SignInButton) findViewById(R.id.btn_sign_in);
imgProfilePic = (ImageView) findViewById(R.id.imgProfilePic);
//google api client initialize
GoogleApiClient.Builder builder = new GoogleApiClient.Builder(this);
builder.addConnectionCallbacks(this);
builder.addOnConnectionFailedListener(this);
builder.addApi(Plus.API);
builder.addScope(Plus.SCOPE_PLUS_LOGIN);
mGoogleApiClient = builder.build();
}
@Override
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
@Override
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RC_SIGN_IN) {
if (resultCode != RESULT_OK) {
mSignInClicked = false;
}
mIntentInProgress = false;
if (!mGoogleApiClient.isConnecting()) {
mGoogleApiClient.connect();
}
}
}
@Override
public void onConnected(Bundle bundle) {
mSignInClicked = false;
Toast.makeText(this, "User is connected!", Toast.LENGTH_LONG).show();
// Get user's information
getProfileInformation();
// Update the UI after signin
updateUI(true);
}
@Override
public void onConnectionSuspended(int i) {
mGoogleApiClient.connect();
updateUI(false);
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
if (!connectionResult.hasResolution()) {
GooglePlayServicesUtil.getErrorDialog(connectionResult.getErrorCode(), this, 0).show();
return;
}
if (!mIntentInProgress) {
// Store the ConnectionResult for later usage
mConnectionResult = connectionResult;
if (mSignInClicked) {
// The user has already clicked 'sign-in' so we attempt to
// resolve all
// errors until the user is signed in, or they cancel.
resolveSignInError();
}
}
}
private void updateUI(boolean isSignedIn) {
if (isSignedIn) {
btnSignIn.setVisibility(View.GONE);
//btnSignOut.setVisibility(View.VISIBLE);
//btnRevokeAccess.setVisibility(View.VISIBLE);
//llProfileLayout.setVisibility(View.VISIBLE);
} else {
btnSignIn.setVisibility(View.VISIBLE);
//btnSignOut.setVisibility(View.GONE);
//btnRevokeAccess.setVisibility(View.GONE);
//llProfileLayout.setVisibility(View.GONE);
}
}
private void signInWithGplus() {
if (!mGoogleApiClient.isConnecting()) {
mSignInClicked = true;
resolveSignInError();
}
}
private void resolveSignInError() {
if (mConnectionResult.hasResolution()) {
try {
mIntentInProgress = true;
mConnectionResult.startResolutionForResult(this, RC_SIGN_IN);
} catch (IntentSender.SendIntentException e) {
mIntentInProgress = false;
mGoogleApiClient.connect();
}
}
}
private void getProfileInformation() {
try {
if (Plus.PeopleApi.getCurrentPerson(mGoogleApiClient) != null) {
Person currentPerson = Plus.PeopleApi
.getCurrentPerson(mGoogleApiClient);
String personName = currentPerson.getDisplayName();
String personPhotoUrl = currentPerson.getImage().getUrl();
String personGooglePlusProfile = currentPerson.getUrl();
String email = Plus.AccountApi.getAccountName(mGoogleApiClient);
Log.e(TAG, "Name: " + personName + ", plusProfile: " + personGooglePlusProfile + ", email: " + email + ", Image: " + personPhotoUrl);
//txtName.setText(personName);
//txtEmail.setText(email);
// by default the profile url gives 50x50 px image only
// we can replace the value with whatever dimension we want by
// replacing sz=X
personPhotoUrl = personPhotoUrl.substring(0,
personPhotoUrl.length() - 2)
+ PROFILE_PIC_SIZE;
new LoadProfileImage(imgProfilePic).execute(personPhotoUrl);
} else {
Toast.makeText(getApplicationContext(),
"Person information is null", Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
e.printStackTrace();
}
}
private class LoadProfileImage extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage;
public LoadProfileImage(ImageView bmImage) {
this.bmImage = bmImage;
}
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return mIcon11;
}
protected void onPostExecute(Bitmap result) {
bmImage.setImageBitmap(result);
}
}
}