我在这里做了检索联系人姓名教程:https://developer.android.com/training/contacts-provider/retrieve-names.html 我可以按照以下方式导入以下内容:
import android.provider.ContactsContract;
import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.widget.AdapterView;
public class ContactsFragment extends Fragment implements
LoaderManager.LoaderCallbacks<Cursor>,
AdapterView.OnItemClickListener {
}
然而,我收到错误,如
错误:(125,9)错误:预期的类,接口或枚举
当我将以下代码放入MainActivity.java文件中时,该文件应该是定义全局变量并且构建失败:
/*
* Defines an array that contains column names to move from
* the Cursor to the ListView.
*/
@SuppressLint("InlinedApi")
private final static String[] FROM_COLUMNS = {
Build.VERSION.SDK_INT
>= Build.VERSION_CODES.HONEYCOMB ?
Contacts.DISPLAY_NAME_PRIMARY :
Contacts.DISPLAY_NAME
};
/*
* Defines an array that contains resource ids for the layout views
* that get the Cursor column contents. The id is pre-defined in
* the Android framework, so it is prefaced with "android.R.id"
*/
private final static int[] TO_IDS = {
android.R.id.text1
};
// Define global mutable variables
// Define a ListView object
ListView mContactsList;
// Define variables for the contact the user selects
// The contact's _ID value
long mContactId;
// The contact's LOOKUP_KEY
String mContactKey;
// A content URI for the selected contact
Uri mContactUri;
// An adapter that binds the result Cursor to the ListView
private SimpleCursorAdapter mCursorAdapter;
如何解决这个问题?
这是gradle文件:
apply plugin: 'com.android.application'
repositories {
mavenLocal()
flatDir {
dirs 'libs'
}
}
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "com.google.firebase.codelab.friendlychat"
minSdkVersion 14
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
packagingOptions {
exclude 'META-INF/LICENSE'
exclude 'META-INF/LICENSE-FIREBASE.txt'
exclude 'META-INF/NOTICE'
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:design:25.1.1'
compile 'com.github.bumptech.glide:glide:3.7.0'
compile 'de.hdodenhof:circleimageview:1.3.0'
compile 'com.android.support:appcompat-v7:25.1.1'
compile 'com.google.android.gms:play-services-auth:10.2.0'
compile 'com.google.firebase:firebase-database:10.2.0'
compile 'com.google.firebase:firebase-storage:10.2.0'
compile 'com.google.firebase:firebase-auth:10.2.0'
compile 'com.google.firebase:firebase-config:10.2.0'
compile 'com.google.android.gms:play-services-appinvite:10.2.0'
compile 'com.google.firebase:firebase-messaging:10.2.0'
compile 'com.google.android.gms:play-services-ads:10.2.0'
compile 'com.google.firebase:firebase-crash:10.2.0'
compile 'com.google.firebase:firebase-appindexing:10.2.0'
compile 'com.firebaseui:firebase-ui-database:0.4.0'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
testCompile 'junit:junit:4.12'
androidTestCompile 'junit:junit:4.12'
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'
androidTestCompile 'com.android.support.test:runner:0.5'
androidTestCompile 'com.android.support:support-annotations:25.1.1'
}
apply plugin: 'com.google.gms.google-services'
在上面,当变量放在MainActivity下时,它会在此代码中留下一个无效方法错误的问题:
// Empty public constructor, required by the system
public ContactsFragment() {}
// A UI Fragment must inflate its View
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the fragment layout
return inflater.inflate(R.layout.contact_list_fragment,
container, false);
}
class ContactsFragment extends Fragment implements
LoaderManager.LoaderCallbacks<Cursor>,
AdapterView.OnItemClickListener {
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
return null;
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
}
/**
* Callback method to be invoked when an item in this AdapterView has
* been clicked.
* <p>
* Implementers can call getItemAtPosition(position) if they need
* to access the data associated with the selected item.
*
* @param parent The AdapterView where the click happened.
* @param view The view within the AdapterView that was clicked (this
* will be a view provided by the adapter)
* @param position The position of the view in the adapter.
* @param id The row id of the item that was clicked.
*/
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
}
}
从这里开始:
package com.google.firebase.codelab.friendlychat;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.CursorLoader;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.Loader;
import android.support.v4.widget.SimpleCursorAdapter;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.Editable;
import android.text.InputFilter;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CursorAdapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdView;
import com.google.android.gms.appinvite.AppInviteInvitation;
import com.google.android.gms.auth.api.Auth;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.analytics.FirebaseAnalytics;
import com.google.firebase.appindexing.Action;
import com.google.firebase.appindexing.FirebaseAppIndex;
import com.google.firebase.appindexing.FirebaseUserActions;
import com.google.firebase.appindexing.Indexable;
import com.google.firebase.appindexing.builders.Actions;
import com.google.firebase.appindexing.builders.Indexables;
import com.google.firebase.appindexing.builders.PersonBuilder;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.crash.FirebaseCrash;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.remoteconfig.FirebaseRemoteConfig;
import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;
import com.google.firebase.storage.UploadTask;
import java.util.HashMap;
import java.util.Map;
import de.hdodenhof.circleimageview.CircleImageView;
import android.provider.ContactsContract;
import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.widget.AdapterView;
public class MainActivity extends AppCompatActivity implements
GoogleApiClient.OnConnectionFailedListener {
/*
* Defines an array that contains column names to move from
* the Cursor to the ListView.
*/
/*
* Defines an array that contains column names to move from
* the Cursor to the ListView.
*/
@SuppressLint("InlinedApi")
private final static String[] FROM_COLUMNS = {
Build.VERSION.SDK_INT
>= Build.VERSION_CODES.HONEYCOMB ?
ContactsContract.Contacts.DISPLAY_NAME_PRIMARY :
ContactsContract.Contacts.DISPLAY_NAME
};
/*
* Defines an array that contains resource ids for the layout views
* that get the Cursor column contents. The id is pre-defined in
* the Android framework, so it is prefaced with "android.R.id"
*/
private final static int[] TO_IDS = {
android.R.id.text1
};
// Define global mutable variables
// Define a ListView object
ListView mContactsList;
// Define variables for the contact the user selects
// The contact's _ID value
long mContactId;
// The contact's LOOKUP_KEY
String mContactKey;
// A content URI for the selected contact
Uri mContactUri;
// An adapter that binds the result Cursor to the ListView
private SimpleCursorAdapter mCursorAdapter;
// Empty public constructor, required by the system
public ContactsFragment() {}
// A UI Fragment must inflate its View
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the fragment layout
return inflater.inflate(R.layout.contact_list_fragment,
container, false);
}
class ContactsFragment extends Fragment implements
LoaderManager.LoaderCallbacks<Cursor>,
AdapterView.OnItemClickListener {
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
return null;
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
}
/**
* Callback method to be invoked when an item in this AdapterView has
* been clicked.
* <p>
* Implementers can call getItemAtPosition(position) if they need
* to access the data associated with the selected item.
*
* @param parent The AdapterView where the click happened.
* @param view The view within the AdapterView that was clicked (this
* will be a view provided by the adapter)
* @param position The position of the view in the adapter.
* @param id The row id of the item that was clicked.
*/
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
}
}
/**
* ATTENTION: This was auto-generated to implement the App Indexing API.
* See https://g.co/AppIndexing/AndroidStudio for more information.
*/
public Action getIndexApiAction() {
return Actions.newView("Main", "http://friendlychat.firebase.google.com/message");
}
@Override
public void onStart() {
super.onStart();
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
FirebaseUserActions.getInstance().start(getIndexApiAction());
}
@Override
public void onStop() {
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
FirebaseUserActions.getInstance().end(getIndexApiAction());
super.onStop();
}
public static class MessageViewHolder extends RecyclerView.ViewHolder {
public TextView messageTextView;
public ImageView messageImageView;
public TextView messengerTextView;
public CircleImageView messengerImageView;
public MessageViewHolder(View v) {
super(v);
messageTextView = (TextView) itemView.findViewById(R.id.messageTextView);
messageImageView = (ImageView) itemView.findViewById(R.id.messageImageView);
messengerTextView = (TextView) itemView.findViewById(R.id.messengerTextView);
messengerImageView = (CircleImageView) itemView.findViewById(R.id.messengerImageView);
}
}
private static final String TAG = "MainActivity";
public static final String MESSAGES_CHILD = "messages";
private static final int REQUEST_INVITE = 1;
private static final int REQUEST_IMAGE = 2;
public static final int DEFAULT_MSG_LENGTH_LIMIT = 10;
public static final String ANONYMOUS = "anonymous";
private static final String MESSAGE_SENT_EVENT = "message_sent";
private static final String MESSAGE_URL = "http://friendlychat.firebase.google.com/message/";
private static final String LOADING_IMAGE_URL = "https://www.google.com/images/spin-32.gif";
private String mUsername;
private String mPhotoUrl;
private SharedPreferences mSharedPreferences;
private Button mSendButton;
private RecyclerView mMessageRecyclerView;
private LinearLayoutManager mLinearLayoutManager;
private FirebaseRecyclerAdapter<FriendlyMessage, MessageViewHolder> mFirebaseAdapter;
private ProgressBar mProgressBar;
private DatabaseReference mFirebaseDatabaseReference;
private FirebaseAuth mFirebaseAuth;
private FirebaseUser mFirebaseUser;
private FirebaseAnalytics mFirebaseAnalytics;
private EditText mMessageEditText;
private ImageView mAddMessageImageView;
private AdView mAdView;
private FirebaseRemoteConfig mFirebaseRemoteConfig;
private GoogleApiClient mGoogleApiClient;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
mUsername = ANONYMOUS;
// Initialize Firebase Auth
mFirebaseAuth = FirebaseAuth.getInstance();
mFirebaseUser = mFirebaseAuth.getCurrentUser();
if (mFirebaseUser == null) {
// Not signed in, launch the Sign In activity
startActivity(new Intent(this, SignInActivity.class));
finish();
return;
} else {
mUsername = mFirebaseUser.getDisplayName();
mPhotoUrl = mFirebaseUser.getPhotoUrl().toString();
}
mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)
.addApi(Auth.GOOGLE_SIGN_IN_API)
.build();
mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
mMessageRecyclerView = (RecyclerView) findViewById(R.id.messageRecyclerView);
mLinearLayoutManager = new LinearLayoutManager(this);
mLinearLayoutManager.setStackFromEnd(true);
mFirebaseDatabaseReference = FirebaseDatabase.getInstance().getReference();
mFirebaseAdapter = new FirebaseRecyclerAdapter<FriendlyMessage, MessageViewHolder>(
FriendlyMessage.class,
R.layout.item_message,
MessageViewHolder.class,
mFirebaseDatabaseReference.child(MESSAGES_CHILD)) {
@Override
protected FriendlyMessage parseSnapshot(DataSnapshot snapshot) {
FriendlyMessage friendlyMessage = super.parseSnapshot(snapshot);
if (friendlyMessage != null) {
friendlyMessage.setId(snapshot.getKey());
}
return friendlyMessage;
}
@Override
protected void populateViewHolder(final MessageViewHolder viewHolder,
FriendlyMessage friendlyMessage, int position) {
mProgressBar.setVisibility(ProgressBar.INVISIBLE);
if (friendlyMessage.getText() != null) {
viewHolder.messageTextView.setText(friendlyMessage.getText());
viewHolder.messageTextView.setVisibility(TextView.VISIBLE);
viewHolder.messageImageView.setVisibility(ImageView.GONE);
} else {
String imageUrl = friendlyMessage.getImageUrl();
if (imageUrl.startsWith("gs://")) {
StorageReference storageReference = FirebaseStorage.getInstance()
.getReferenceFromUrl(imageUrl);
storageReference.getDownloadUrl().addOnCompleteListener(
new OnCompleteListener<Uri>() {
@Override
public void onComplete(@NonNull Task<Uri> task) {
if (task.isSuccessful()) {
String downloadUrl = task.getResult().toString();
Glide.with(viewHolder.messageImageView.getContext())
.load(downloadUrl)
.into(viewHolder.messageImageView);
} else {
Log.w(TAG, "Getting download url was not successful.",
task.getException());
}
}
});
} else {
Glide.with(viewHolder.messageImageView.getContext())
.load(friendlyMessage.getImageUrl())
.into(viewHolder.messageImageView);
}
viewHolder.messageImageView.setVisibility(ImageView.VISIBLE);
viewHolder.messageTextView.setVisibility(TextView.GONE);
}
viewHolder.messengerTextView.setText(friendlyMessage.getName());
if (friendlyMessage.getPhotoUrl() == null) {
viewHolder.messengerImageView.setImageDrawable(ContextCompat.getDrawable(MainActivity.this,
R.drawable.ic_account_circle_black_36dp));
} else {
Glide.with(MainActivity.this)
.load(friendlyMessage.getPhotoUrl())
.into(viewHolder.messengerImageView);
}
if (friendlyMessage.getText() != null) {
// write this message to the on-device index
FirebaseAppIndex.getInstance().update(getMessageIndexable(friendlyMessage));
}
// log a view action on it
FirebaseUserActions.getInstance().end(getMessageViewAction(friendlyMessage));
}
};
mFirebaseAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
@Override
public void onItemRangeInserted(int positionStart, int itemCount) {
super.onItemRangeInserted(positionStart, itemCount);
int friendlyMessageCount = mFirebaseAdapter.getItemCount();
int lastVisiblePosition = mLinearLayoutManager.findLastCompletelyVisibleItemPosition();
// If the recycler view is initially being loaded or the user is at the bottom of the list, scroll
// to the bottom of the list to show the newly added message.
if (lastVisiblePosition == -1 ||
(positionStart >= (friendlyMessageCount - 1) && lastVisiblePosition == (positionStart - 1))) {
mMessageRecyclerView.scrollToPosition(positionStart);
}
}
});
mMessageRecyclerView.setLayoutManager(mLinearLayoutManager);
mMessageRecyclerView.setAdapter(mFirebaseAdapter);
// Initialize and request AdMob ad.
mAdView = (AdView) findViewById(R.id.adView);
AdRequest adRequest = new AdRequest.Builder().build();
mAdView.loadAd(adRequest);
// Initialize Firebase Measurement.
mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);
// Initialize Firebase Remote Config.
mFirebaseRemoteConfig = FirebaseRemoteConfig.getInstance();
// Define Firebase Remote Config Settings.
FirebaseRemoteConfigSettings firebaseRemoteConfigSettings =
new FirebaseRemoteConfigSettings.Builder()
.setDeveloperModeEnabled(true)
.build();
// Define default config values. Defaults are used when fetched config values are not
// available. Eg: if an error occurred fetching values from the server.
Map<String, Object> defaultConfigMap = new HashMap<>();
defaultConfigMap.put("friendly_msg_length", 10L);
// Apply config settings and default values.
mFirebaseRemoteConfig.setConfigSettings(firebaseRemoteConfigSettings);
mFirebaseRemoteConfig.setDefaults(defaultConfigMap);
// Fetch remote config.
fetchConfig();
mMessageEditText = (EditText) findViewById(R.id.messageEditText);
mMessageEditText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(mSharedPreferences
.getInt(CodelabPreferences.FRIENDLY_MSG_LENGTH, DEFAULT_MSG_LENGTH_LIMIT))});
mMessageEditText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
if (charSequence.toString().trim().length() > 0) {
mSendButton.setEnabled(true);
} else {
mSendButton.setEnabled(false);
}
}
@Override
public void afterTextChanged(Editable editable) {
}
});
mAddMessageImageView = (ImageView) findViewById(R.id.addMessageImageView);
mAddMessageImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
startActivityForResult(intent, REQUEST_IMAGE);
}
});
mSendButton = (Button) findViewById(R.id.sendButton);
mSendButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
FriendlyMessage friendlyMessage = new FriendlyMessage(mMessageEditText.getText().toString(), mUsername,
mPhotoUrl, null);
mFirebaseDatabaseReference.child(MESSAGES_CHILD).push().setValue(friendlyMessage);
mMessageEditText.setText("");
mFirebaseAnalytics.logEvent(MESSAGE_SENT_EVENT, null);
}
});
}
private Action getMessageViewAction(FriendlyMessage friendlyMessage) {
return new Action.Builder(Action.Builder.VIEW_ACTION)
.setObject(friendlyMessage.getName(), MESSAGE_URL.concat(friendlyMessage.getId()))
.setMetadata(new Action.Metadata.Builder().setUpload(false))
.build();
}
}
答案 0 :(得分:0)
似乎在MainActivity.java
你忘了申报课程。确保您正确定义了类
public class MainActivity.java