我是编码入门者。我尝试制作android提醒应用。我正在使用Firebase实时数据库存储数据,并且将数据检索到我的应用程序中以使用AlarmManager设置提醒,并且它可以提醒警报和通知。但是从手机打开通知后,应用程序崩溃了。任何人都可以帮助我将我的错误代码替换为工作代码?谢谢
XML(activity_detail.xml)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/windowBackground"
tools:context=".DetailActivity">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:maxLines="1"
android:padding="5dp"
android:text="==================DETAIL_ACARA==================="
android:textAppearance="@style/TextAppearance.AppCompat"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/namaDetailTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:padding="5dp"
android:text="RAPAT ANGGOTA"
android:textAppearance="@style/TextAppearance.AppCompat.Large"
android:textColor="#ff6c22"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:id="@+id/tanggalLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:padding="5dp"
android:textColor="#646262"
android:text="TANGGAL : "
android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:textStyle="bold" />
<TextView
android:id="@+id/tanggalDetailTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:padding="5dp"
android:textColor="#646262"
android:text="11 Januari 2019"
android:textAppearance="?android:attr/textAppearanceListItemSmall" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:id="@+id/waktuLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:padding="5dp"
android:textColor="#646262"
android:text="WAKTU : "
android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:textStyle="bold" />
<TextView
android:id="@+id/waktuDetailTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:padding="5dp"
android:textColor="#646262"
android:text="18:00"
android:textAppearance="?android:attr/textAppearanceListItemSmall" />
<TextView
android:id="@+id/wibLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:padding="5dp"
android:textColor="#646262"
android:text="WIB"
android:textAppearance="?android:attr/textAppearanceListItemSmall" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:id="@+id/tempatLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:padding="5dp"
android:textColor="#646262"
android:text="TEMPAT : "
android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:textStyle="bold" />
<TextView
android:id="@+id/tempatDetailTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:padding="5dp"
android:textColor="#646262"
android:text="Student Lounge"
android:textAppearance="?android:attr/textAppearanceListItemSmall" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:id="@+id/batas1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:padding="5dp"
android:text="====================DESKRIPSI====================="
android:textAppearance="@style/TextAppearance.AppCompat"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>
<TextView
android:id="@+id/deskripsiDetailTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textColor="#646262"
android:maxLines="20"
android:padding="5dp"
android:text="Jelasno jall"
android:textAppearance="?android:attr/textAppearanceListItemSmall" />
<TextView
android:id="@+id/batas2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:padding="5dp"
android:textStyle="bold"
android:text="=================================================="
android:textAppearance="@style/TextAppearance.AppCompat" />
<ToggleButton
android:id="@+id/alarmToggle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Alarm On/Off"
android:onClick="onToggleClicked"
android:textOn="Matikan Pengingat"
android:textOff="Ingatkan Saya"/>
</LinearLayout>
</ScrollView>
</RelativeLayout>
JAVA(MainActivity.java)
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
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.BaseAdapter;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import android.support.v7.widget.Toolbar;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseException;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import com.google.firebase.messaging.FirebaseMessaging;
import java.util.ArrayList;
import id.restabayu.clientsatu.Lainlain.Help;
import id.restabayu.clientsatu.Lainlain.Pengurus;
public class MainActivity extends AppCompatActivity {
/**********************************FIREBASE HELPER START************************/
public class FirebaseHelper {
DatabaseReference db;
ArrayList<Classified> classifieds = new ArrayList<>();
ListView mListView;
Context c;
ProgressBar progressBar;
/*
let's receive a reference to our FirebaseDatabase
*/
public FirebaseHelper(DatabaseReference db, Context context, ListView mListView) {
this.db = db;
this.c = context;
this.mListView = mListView;
this.retrieve();
progressBar = (ProgressBar) findViewById(R.id.progressbar);
progressBar.setVisibility(View.VISIBLE);
}
/*
Retrieve and Return them clean data in an arraylist so that they just bind it to ListView.
*/
public ArrayList<Classified> retrieve() {
db.child("classified").addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
classifieds.clear();
if (dataSnapshot.exists() && dataSnapshot.getChildrenCount() > 0) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
//Now get Classified Objects and populate our arraylist.
Classified classified = ds.getValue(Classified.class);
classifieds.add(classified);
}
adapter = new CustomAdapter(c, classifieds);
mListView.setAdapter(adapter);
new Handler().post(new Runnable() {
@Override
public void run() {
mListView.smoothScrollToPosition(classifieds.size());
}
});
}
progressBar.setVisibility(View.GONE);
}
@Override
public void onCancelled(DatabaseError databaseError) {
Log.d("mTAG", databaseError.getMessage());
Toast.makeText(c, "ERROR " + databaseError.getMessage(), Toast.LENGTH_LONG).show();
}
});
return classifieds;
}
}
/**********************************CUSTOM ADAPTER START************************/
class CustomAdapter extends BaseAdapter {
Context c;
ArrayList<Classified> classifieds;
public CustomAdapter(Context c, ArrayList<Classified> classifieds) {
this.c = c;
this.classifieds = classifieds;
}
@Override
public int getCount() {
return classifieds.size();
}
@Override
public Object getItem(int position) {
return classifieds.get(getCount() - position - 1);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(c).inflate(R.layout.model, parent, false);
}
TextView nameTextView = convertView.findViewById(R.id.nameTextView);
TextView quoteTextView = convertView.findViewById(R.id.quoteTextView);
TextView descriptionTextView = convertView.findViewById(R.id.descriptionTextView);
final Classified s = (Classified) this.getItem(position);
nameTextView.setText(s.getNama());
quoteTextView.setText(s.getDeskripsi());
descriptionTextView.setText(s.getTanggal());
//Saat Acara Di Tap Maka akan membuka detailActivity
convertView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String[] classifieds = {
s.getNama(),
s.getTanggal(),
s.getWaktu(),
s.getTempat(),
s.getDeskripsi(),
};
openDetailActivity(classifieds);
}
});
return convertView;
}
private void openDetailActivity(String[] data)
{
Intent i = new Intent(MainActivity.this, DetailActivity.class);
i.putExtra("NAMA_KEY",data[0]);
i.putExtra("TANGGAL_KEY",data[1]);
i.putExtra("WAKTU_KEY",data[2]);
i.putExtra("TEMPAT_KEY",data[3]);
i.putExtra("DESKRIPSI_KEY",data[4]);
startActivity(i);
}
}
/**********************************TOOLBAR MENU*************************************/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
//nyoboo
case R.id.menuPengurus:
startActivity(new Intent(this, Pengurus.class));
break;
case R.id.menuHelp:
startActivity(new Intent(this, Help.class));
break;
case R.id.menuLogout:
new AlertDialog.Builder(this, R.style.AlertDialogLogout)
.setTitle("Yakin Ingin Logout ?")
.setPositiveButton("Ya", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which) {
FirebaseAuth.getInstance().signOut();
finish();
startActivity(new Intent(MainActivity.this, Goodbye.class));
}
})
.setNegativeButton("Tidak", null)
.show();
break;
}
return true;
}
/************************************EXIT DIALOG************************************/
@Override
public void onBackPressed() {
new AlertDialog.Builder(this, R.style.AlertDialogStyle)
.setTitle("Apakah anda yakin ingin keluar ?")
.setPositiveButton("Ya", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
})
.setNegativeButton("Tidak", null)
.show();
}
/**********************************MAIN ACTIVITY CONTINUATION************************/
//instance fields
DatabaseReference db;
FirebaseHelper helper;
CustomAdapter adapter;
ListView mListView;
FirebaseAuth mAuth;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//nyobo
mAuth = FirebaseAuth.getInstance();
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
toolbar.setTitleTextColor(getResources().getColor(android.R.color.white));
FirebaseMessaging.getInstance().subscribeToTopic("news");
mListView = (ListView) findViewById(R.id.myListView);
//initialize firebase database
db = FirebaseDatabase.getInstance().getReference();
helper = new FirebaseHelper(db, this, mListView);
}
}
JAVA(DetailActivity.java)
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;
import java.util.Calendar;
import java.util.Date;
import java.lang.String;
import id.restabayu.clientsatu.Service.AlarmReciever;
import id.restabayu.clientsatu.Service.Converter;
import id.restabayu.clientsatu.Service.AlarmService;
public class DetailActivity extends AppCompatActivity {
TextView namaTxt,tanggalTxt,waktuTxt,tempatTxt,deskripsiTxt;
AlarmManager alarmManager;
private PendingIntent pendingIntent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
namaTxt = (TextView) findViewById(R.id.namaDetailTextView);
tanggalTxt = (TextView) findViewById(R.id.tanggalDetailTextView);
waktuTxt = (TextView) findViewById(R.id.waktuDetailTextView);
tempatTxt = (TextView) findViewById(R.id.tempatDetailTextView);
deskripsiTxt = (TextView) findViewById(R.id.deskripsiDetailTextView);
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
ToggleButton alarmToggle = (ToggleButton) findViewById(R.id.alarmToggle);
//GET INTENT
Intent i = this.getIntent();
//RECEIVE DATA
String nama = i.getExtras().getString("NAMA_KEY");
String tanggal = i.getExtras().getString("TANGGAL_KEY");
String waktu = i.getExtras().getString("WAKTU_KEY");
String tempat = i.getExtras().getString("TEMPAT_KEY");
String deskripsi = i.getExtras().getString("DESKRIPSI_KEY");
//BIND DATA
namaTxt.setText(nama);
tanggalTxt.setText(tanggal);
waktuTxt.setText(waktu);
tempatTxt.setText(tempat);
deskripsiTxt.setText(deskripsi);
}
public void onToggleClicked (View view) {
String date = Converter.ConvertDate(tanggalTxt.getText().toString(), "dd/MM/yyyy", "yyyy MM dd");
String time = waktuTxt.getText().toString();
String dateTime = date + " " + time;
Date txtAlarm = Converter.toDate(dateTime, "yyyy MM dd HH:mm");
if (((ToggleButton) view).isChecked()) {
Log.d("MyActivity", "Alarm On");
Calendar calendar = Calendar.getInstance();
calendar.setTime(txtAlarm);
Intent myIntent = new Intent(this, AlarmReciever.class);
pendingIntent = PendingIntent.getBroadcast(DetailActivity.this, 0, myIntent, 0);
alarmManager.set(AlarmManager.RTC, calendar.getTimeInMillis(), pendingIntent);
}
else {
alarmManager.cancel(pendingIntent);
Log.d("MyActivity", "Alarm Off");
}
}
}
JAVA(AlarmService.java)
import android.app.IntentService;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Build;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import android.widget.Toast;
import java.util.Random;
import id.restabayu.clientsatu.DetailActivity;
import id.restabayu.clientsatu.R;
public class AlarmService extends IntentService {
private NotificationManager alarmNotificationManager;
public AlarmService() {
super("AlarmService");
}
@Override
public void onHandleIntent(Intent intent) {
//sendNotification("Tangi gan!");
showNotification("PENGINGAT !", "Acara Segera Dimulai ! Silahkan Mempersiapkan Diri");
}
private void sendNotification(String msg) {
Log.d("AlarmService", "Preparing to send notification...: " + msg);
Toast.makeText(this, "Alarm Notif Show", Toast.LENGTH_LONG).show();
alarmNotificationManager = (NotificationManager) this
.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, DetailActivity.class), 0);
NotificationCompat.Builder alamNotificationBuilder = new NotificationCompat.Builder(
this).setContentTitle("Alarm").setSmallIcon(R.drawable.ic_launcher_background)
.setStyle(new NotificationCompat.BigTextStyle().bigText(msg))
.setContentText(msg);
alamNotificationBuilder.setContentIntent(contentIntent);
alarmNotificationManager.notify(1, alamNotificationBuilder.build());
Log.d("AlarmService", "Notification sent.");
}
private void showNotification(String title, String body) {
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, DetailActivity.class), 0);
NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
String NOTIFICATION_CHANNEL_ID = "id.restabayu.clientsatu.test";
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID,"Notification",NotificationManager.IMPORTANCE_DEFAULT);
notificationChannel.setDescription("IK Channel");
notificationChannel.enableLights(true);
notificationChannel.setLightColor(Color.BLUE);
notificationChannel.setVibrationPattern(new long[]{0,1000,500,1000});
notificationChannel.enableLights(true);
notificationManager.createNotificationChannel(notificationChannel);
}
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this,NOTIFICATION_CHANNEL_ID);
notificationBuilder.setAutoCancel(true)
.setDefaults(Notification.DEFAULT_ALL)
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.drawable.ic_launcher_background)
.setContentTitle(title)
.setContentText(body)
.setContentInfo("info")
.setContentIntent(contentIntent);
notificationManager.notify(new Random().nextInt(),notificationBuilder.build());
}
}
Logcat
原因:java.lang.NullPointerException:尝试在id.restabayu.clientsatu上的空对象引用上调用虚拟方法'java.lang.String android.os.Bundle.getString(java.lang.String)'。 DetailActivity.onCreate(DetailActivity.java:52)
答案 0 :(得分:0)
替换此`
Intent i = this.getIntent();
//RECEIVE DATA
String nama = i.getExtras().getString("NAMA_KEY");
String tanggal = i.getExtras().getString("TANGGAL_KEY");
String waktu = i.getExtras().getString("WAKTU_KEY");
String tempat = i.getExtras().getString("TEMPAT_KEY");
String deskripsi = i.getExtras().getString("DESKRIPSI_KEY");
` 与
Intent i = this.getIntent();
Bundle b = i.getExtras();
if (b != null) {
String nama = b.getString("NAMA_KEY", "none");
String tanggal = b.getString("TANGGAL_KEY", "none");
String waktu = b.getString("WAKTU_KEY", "none");
String tempat = b.getString("TEMPAT_KEY", "none");
String deskripsi = b.getString("DESKRIPSI_KEY", "none");
}
inDetailActivity
答案 1 :(得分:0)
您将一些数据从MainActivity.java发送到DetailActivity.java,它的工作原理如我所见,但是当您从通知中打开DetailActivity
时,您没有发送该数据,这会导致错误。您必须从AlarmService将数据(分类)发送到MainActivity之类的DetailsActivity
1)更改AlarmService.java
showNotification()
的功能
String[] datas = {Your_DATA1,Your_DATA2}; // replace and send your data from here
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
getIntentt(datas), 0);
并创建getIntentt
函数
private Intent getIntentt(String[] data) {
Intent i = new Intent(this, DetailActivity.class);
i.putExtra("NAMA_KEY",data[0]);
i.putExtra("TANGGAL_KEY",data[1]);
i.putExtra("WAKTU_KEY",data[2]);
i.putExtra("TEMPAT_KEY",data[3]);
i.putExtra("DESKRIPSI_KEY",data[4]);
return i;
}
您使用了一个额外的逗号,请删除其中的功能错误
String[] classifieds = {
s.getNama(),
s.getTanggal(),
s.getWaktu(),
s.getTempat(),
s.getDeskripsi(), // here this comma , REMOVE it
};