作为Android主题的新内容,我一直在阅读和阅读课程/教程。我理解活动协议,但现在我已经陷入了碎片,并尝试使用Google Calendar API将简单的应用放在一起。但是,我很难抓住更新碎片"来自MainActivity部分。
此时,应用程序崩溃了 我已经尝试过一切可以完成这项工作,但没有成功:(你怎么做到这一点?
这是MainActivity:
public class MainActivity extends Activity
implements NavigationDrawerFragment.NavigationDrawerCallbacks {
com.google.api.services.calendar.Calendar mService;
GoogleAccountCredential credential;
public TextView mStatusText;
public TextView mEventText;
final HttpTransport transport = AndroidHttp.newCompatibleTransport();
final JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
static final int REQUEST_ACCOUNT_PICKER = 1000;
static final int REQUEST_AUTHORIZATION = 1001;
static final int REQUEST_GOOGLE_PLAY_SERVICES = 1002;
private static final String PREF_ACCOUNT_NAME = "accountName";
private static final String[] SCOPES = {CalendarScopes.CALENDAR_READONLY};
/**
* Fragment managing the behaviors, interactions and presentation of the navigation drawer.
*/
private NavigationDrawerFragment mNavigationDrawerFragment;
/**
* Used to store the last screen title. For use in {@link #restoreActionBar()}.
*/
private CharSequence mTitle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mNavigationDrawerFragment = (NavigationDrawerFragment)
getFragmentManager().findFragmentById(R.id.navigation_drawer);
mTitle = getTitle();
// Set up the drawer.
mNavigationDrawerFragment.setUp(
R.id.navigation_drawer,
(DrawerLayout) findViewById(R.id.drawer_layout));
// Initialize credentials and calendar service.
SharedPreferences settings = getPreferences(Context.MODE_PRIVATE);
credential = GoogleAccountCredential.usingOAuth2(
getApplicationContext(), Arrays.asList(SCOPES))
.setBackOff(new ExponentialBackOff())
.setSelectedAccountName(settings.getString(PREF_ACCOUNT_NAME, null));
mService = new com.google.api.services.calendar.Calendar.Builder(
transport, jsonFactory, credential)
.setApplicationName("Calendar API Android Quickstart")
.build();
}
@Override
public void onNavigationDrawerItemSelected(int position) {
Fragment fragment = null;
switch (position) {
case 0:
fragment = new Noticias_Fragment();
break;
case 1:
fragment = new Eventos_Fragment();
break;
case 2:
fragment = new Quienes_Fragment();
break;
case 3:
fragment = new Contacto_Fragment();
break;
}
// update the main content by replacing fragments
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.container, fragment)
.commit();
}
public void onSectionAttached(int number) {
switch (number) {
case 1:
mTitle = getString(R.string.title_section1);
break;
case 2:
mTitle = getString(R.string.title_section2);
break;
case 3:
mTitle = getString(R.string.title_section3);
break;
case 4:
mTitle = getString(R.string.title_section4);
break;
}
}
public void restoreActionBar() {
ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setTitle(mTitle);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
if (!mNavigationDrawerFragment.isDrawerOpen()) {
// Only show items in the action bar relevant to this screen
// if the drawer is not showing. Otherwise, let the drawer
// decide what to show in the action bar.
getMenuInflater().inflate(R.menu.main, menu);
restoreActionBar();
return true;
}
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
private static final String ARG_SECTION_NUMBER = "section_number";
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
public PlaceholderFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
return rootView;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
((MainActivity) activity).onSectionAttached(
getArguments().getInt(ARG_SECTION_NUMBER));
}
}
public void ButtonOnClick(View v) {
switch (v.getId()) {
case R.id.imageButton: //botón Mail
Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
emailIntent.setType("text/plain");
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[]{"elmaildefresh@gmail.com"});
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "Motivo");
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, "Escribe tu texto a enviar");
startActivity(Intent.createChooser(emailIntent, "Elije tu gestor de correo..."));
break;
case R.id.imageButton2: //botón Página
Intent intent2 = new Intent(Intent.ACTION_VIEW);
intent2.setData(Uri.parse("http://www.lapaginadelfreshxalapa.com"));
startActivity(intent2);
break;
case R.id.imageButton3: //botón FB
Intent intent3 = new Intent(Intent.ACTION_VIEW);
intent3.setData(Uri.parse("http://www.facebook.com/freshxalapa"));
startActivity(intent3);
break;
case R.id.imageButton4: //botón TW
Intent intent4 = new Intent(Intent.ACTION_VIEW);
intent4.setData(Uri.parse("http://www.twitter.com/freshxalapa"));
startActivity(intent4);
break;
}
}
/**
* Called whenever this activity is pushed to the foreground, such as after
* a call to onCreate().
*/
@Override
protected void onResume() {
super.onResume();
if (isGooglePlayServicesAvailable()) {
refreshEventList();
} else {
mStatusText.setText("Google Play Services required: " +
"after installing, close and relaunch this app.");
}
}
/**
* Called when an activity launched here (specifically, AccountPicker
* and authorization) exits, giving you the requestCode you started it with,
* the resultCode it returned, and any additional data from it.
* @param requestCode code indicating which activity result is incoming.
* @param resultCode code indicating the result of the incoming
* activity result.
* @param data Intent (containing result data) returned by incoming
* activity result.
*/
@Override
protected void onActivityResult(
int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch(requestCode) {
case REQUEST_GOOGLE_PLAY_SERVICES:
if (resultCode == RESULT_OK) {
refreshEventList();
} else {
isGooglePlayServicesAvailable();
}
break;
case REQUEST_ACCOUNT_PICKER:
if (resultCode == RESULT_OK && data != null &&
data.getExtras() != null) {
String accountName =
data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
if (accountName != null) {
credential.setSelectedAccountName(accountName);
SharedPreferences settings =
getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.putString(PREF_ACCOUNT_NAME, accountName);
editor.commit();
refreshEventList();
}
} else if (resultCode == RESULT_CANCELED) {
mStatusText.setText("Account unspecified.");
}
break;
case REQUEST_AUTHORIZATION:
if (resultCode == RESULT_OK) {
refreshEventList();
} else {
chooseAccount();
}
break;
}
super.onActivityResult(requestCode, resultCode, data);
}
/**
* Attempt to get a list of calendar events to display. If the email
* address isn't known yet, then call chooseAccount() method so the user
* can pick an account.
*/
private void refreshEventList() {
if (credential.getSelectedAccountName() == null) {
chooseAccount();
} else {
if (isDeviceOnline()) {
new EventsFetchTask(this).execute();
} else {
mStatusText.setText("No network connection available.");
}
}
}
/**
* Clear any existing events from the list display and update the header
* message; called from background threads and async tasks that need to
* update the UI (in the UI thread).
*/
public void clearEvents() {
runOnUiThread(new Runnable() {
@Override
public void run() {
mStatusText.setText("Retrieving events…");
mEventText.setText("");
}
});
}
/**
* Fill the event display with the given List of strings; called from
* background threads and async tasks that need to update the UI (in the
* UI thread).
* @param eventStrings a List of Strings to populate the event display with.
*/
public void updateEventList(final List<String> eventStrings) {
runOnUiThread(new Runnable() {
@Override
public void run() {
if (eventStrings == null) {
mStatusText.setText("Error retrieving events!");
} else if (eventStrings.size() == 0) {
mStatusText.setText("No upcoming events found.");
} else {
mStatusText.setText("Your upcoming events retrieved using" +
" the Google Calendar API:");
mEventText.setText(TextUtils.join("\n\n", eventStrings));
}
}
});
}
/**
* Show a status message in the list header TextView; called from background
* threads and async tasks that need to update the UI (in the UI thread).
* @param message a String to display in the UI header TextView.
*/
public void updateStatus(final String message) {
runOnUiThread(new Runnable() {
@Override
public void run() {
mStatusText.setText(message);
}
});
}
/**
* Starts an activity in Google Play Services so the user can pick an
* account.
*/
private void chooseAccount() {
startActivityForResult(
credential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);
}
/**
* Checks whether the device currently has a network connection.
* @return true if the device has a network connection, false otherwise.
*/
private boolean isDeviceOnline() {
ConnectivityManager connMgr =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
return (networkInfo != null && networkInfo.isConnected());
}
/**
* Check that Google Play services APK is installed and up to date. Will
* launch an error dialog for the user to update Google Play Services if
* possible.
* @return true if Google Play Services is available and up to
* date on this device; false otherwise.
*/
private boolean isGooglePlayServicesAvailable() {
final int connectionStatusCode =
GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (GooglePlayServicesUtil.isUserRecoverableError(connectionStatusCode)) {
showGooglePlayServicesAvailabilityErrorDialog(connectionStatusCode);
return false;
} else if (connectionStatusCode != ConnectionResult.SUCCESS ) {
return false;
}
return true;
}
/**
* Display an error dialog showing that Google Play Services is missing
* or out of date.
* @param connectionStatusCode code describing the presence (or lack of)
* Google Play Services on this device.
*/
void showGooglePlayServicesAvailabilityErrorDialog(
final int connectionStatusCode) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Dialog dialog = GooglePlayServicesUtil.getErrorDialog(
connectionStatusCode,
MainActivity.this,
REQUEST_GOOGLE_PLAY_SERVICES);
dialog.show();
}
});
}
}
这是片段:
import android.app.Fragment;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class Eventos_Fragment extends Fragment {
View rootView;
/**
* A Calendar service object used to query or modify calendars via the
* Calendar API. Note: Do not confuse this class with the
* com.google.api.services.calendar.model.Calendar class.
*/
TextView mStatusText;
TextView mEventText;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_evento, container, false);
//Set up event text views for Google API
return rootView;
}
public void changeStatusText(){
//this textview should be bound in the fragment onCreate as a member variable
mStatusText = (TextView) rootView.findViewById(R.id.status_text_view);
mStatusText.setText("Estatus");
}
public void changeEventText(){
//this textview should be bound in the fragment onCreate as a member variable
mEventText = (TextView) rootView.findViewById(R.id.event_text_view);
mEventText.setText("Evento");
}
}
日志:
04-28 18:38:46.751 1557-1557/mx.com.origamilab.fresh E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: mx.com.origamilab.fresh, PID: 1557
java.lang.RuntimeException: Unable to resume activity {mx.com.origamilab.fresh/mx.com.origamilab.fresh.MainActivity}: java.lang.NullPointerException
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2774)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2803)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2238)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at mx.com.origamilab.fresh.MainActivity.onResume(MainActivity.java:258)
at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1192)
at android.app.Activity.performResume(Activity.java:5310)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2764)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2803)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2238)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
答案 0 :(得分:0)
试试这个
替换
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.container, fragment)
.commit();
带
android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.container, fragment).commit();
答案 1 :(得分:0)
mStatusText永远不会初始化为MainActivity中的任何内容。这就是你获得NullPointerException的原因。
您需要使用findViewById对其进行初始化。也许是onResume()实现中的第一件事。