I have created a service in my application and called the function that starts the service using a button using onClick in xml but the app crashes.
some help will be appreciated.
package slide.apptech.com.nav;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.StrictMode;
import android.support.annotation.Nullable;
import android.view.View;
import android.support.design.widget.NavigationView;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.support.design.widget.FloatingActionButton;
import java.util.ArrayList;
import java.util.Calendar;
import static java.util.Calendar.*;
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
private static String TAG = MainActivity.class.getSimpleName();
private Intent myIntent;
Button Refresh;
TextView updated;
//related to main screen list view
ListView lv;
Context context;
ArrayList prgmName;
public static int [] prgmImages={R.drawable.temp,R.drawable.hum,R.drawable.press,R.drawable.amb,R.drawable.alt};
public static String [] prgmNameList={" Temperature: "," Humidity: "," Pressure: "," Ambient Light:"," Altitude: "};
//GetFromServer gs1=new GetFromServer();
public String [] prgmVal={"1","2","3","4","5"};
public static String [] prgmUnit={" °C"," %"," hPa"," lx"," m"};
//public String datentime=gs1.DateNTime[0];
String datentime;
//boolean variable to indicate if the arrays have been set or not
Boolean arraysset;
GetFromServer gs1;
public ArrayList<String> atList=new ArrayList<String>();
public ArrayList<String> dataList=new ArrayList<String>();
#Override
protected void onCreate(Bundle savedInstanceState) {
//these lines overite all the warnings by android to restrict large tasks
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
lv = (ListView) findViewById(R.id.listView);
updated=(TextView)findViewById((R.id.datentime));
Refresh = (Button) findViewById(R.id.refresh);
//block related to main screen list view
//creating a object from getfromserver class to give a request to server
gs1=new GetFromServer();
new loadSomeStuff().execute();
updated.setText(datentime);
prgmVal[0]=Double.toString(gs1.Temperature[0]);
prgmVal[1]=Double.toString(gs1.Humidity[0]);
prgmVal[2]=Double.toString(gs1.Pressure[0]);
prgmVal[3]=Double.toString(gs1.Ambient[0]);
prgmVal[4]=Double.toString(gs1.Altitude[0]);
datentime="Updated on :"+gs1.DateNTime[0];
context = this;
//this adapter is defined in custom adapter
// see class for all the constructors
lv.setAdapter(new CustomAdapter(MainActivity.this, MainActivity.prgmNameList, MainActivity.prgmImages, prgmVal, MainActivity.prgmUnit));
//code related to refresh button the main screen find xml in content_main
Refresh.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startService(new Intent(getBaseContext(),service.class));
//Toast.makeText(context, "Please wait!", Toast.LENGTH_LONG).show();
gs1 = new GetFromServer();
gs1.sendData();
gs1.setArray();
//codeline to start athe service
prgmVal[0] = Double.toString(gs1.Temperature[0]);
prgmVal[1] = Double.toString(gs1.Humidity[0]);
prgmVal[2] = Double.toString(gs1.Pressure[0]);
prgmVal[3] = Double.toString(gs1.Ambient[0]);
prgmVal[4] = Double.toString(gs1.Altitude[0]);
String datentime = "Updated on :" + gs1.DateNTime[0];
updated.setText(datentime);
context = MainActivity.this;
lv.setAdapter(new CustomAdapter(MainActivity.this, MainActivity.prgmNameList, MainActivity.prgmImages, prgmVal, MainActivity.prgmUnit));
//Toast.makeText(context, "Refreshed!!!", Toast.LENGTH_LONG).show();
}
});
//this code is for a floation button see xml
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent myIntent = new Intent(MainActivity.this,Faq.class);
startActivity(myIntent);
}
});
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
}
//this is code related to back button in action bar to close drawer if open else go back to previous activity
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#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();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
//app crash due to following code
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (id == R.id.liConnection) {
drawer.closeDrawer(GravityCompat.START);
Intent myIntent = new Intent(MainActivity.this, Connect.class);
startActivity(myIntent);
}
else if (id == R.id.liRanges){
drawer.closeDrawer(GravityCompat.START);
Intent myIntent = new Intent(MainActivity.this, Ranges.class);
startActivity(myIntent);
}
else if (id == R.id.liSupport) {
drawer.closeDrawer(GravityCompat.START);
Intent myIntent = new Intent(MainActivity.this, Support.class);
startActivity(myIntent);
}
else if (id == R.id.liAbout) {
drawer.closeDrawer(GravityCompat.START);
Intent myIntent = new Intent(MainActivity.this, AboutUs.class);
startActivity(myIntent);
}
else if (id == R.id.liRateus) {
drawer.closeDrawer(GravityCompat.START);
Intent myIntent = new Intent(MainActivity.this,Rateus.class);
startActivity(myIntent);
}
return true;
}
public void getPosition(int position) {
if (position == 0) {
//code specific to first list item
myIntent = new Intent(MainActivity.this, ChartTemperature.class); //replace connect classs with analysis
startActivity(myIntent);
}
else if (position == 1) {
//code specific to first list item
Intent myIntent = new Intent(MainActivity.this, ChartHumidity.class);
startActivity(myIntent);
}
else if (position == 2) {
//code specific to first list item
Intent myIntent = new Intent(MainActivity.this, ChartPressure.class);
startActivity(myIntent);
}
else if (position == 3) {
//code specific to first list item
Intent myIntent = new Intent(MainActivity.this, ChartAmbient.class);
startActivity(myIntent);
}
else if (position == 4) {
//code specific to first list item
Intent myIntent = new Intent(MainActivity.this, ChartAltitude.class);
startActivity(myIntent);
}
}
// Method to start the service
public void startService(View view) {
startService(new Intent(getBaseContext(), service.class));
}
//here we are creating a async task to reduce load on oncreate method
public class loadSomeStuff extends AsyncTask<String, Integer, Void> {
#Override
protected Void doInBackground(String... params) {
// TODO Auto-generated method stub
try {
gs1.sendData();
gs1.setArray();
prgmVal[0]=Double.toString(gs1.Temperature[0]);
prgmVal[1]=Double.toString(gs1.Humidity[0]);
prgmVal[2]=Double.toString(gs1.Pressure[0]);
prgmVal[3]=Double.toString(gs1.Ambient[0]);
prgmVal[4]=Double.toString(gs1.Altitude[0]);
datentime="Updated on :"+gs1.DateNTime[0];
arraysset = true;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
}
service.java
package slide.apptech.com.nav;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.widget.Toast;
/**
* Created by MOHIT on 17-04-2016.
*/
public class service extends Service{
//creating a server class object
GetFromServer gs1;
//creating a database object
database record;
String value;
boolean tempflag,pressflag,humflag,lightflag;
double temperature,humidity,pressure,light,max,min;
NotificationManager manager;
Notification myNotication;
Context context;
MainActivity main;
public final String UPDATE_DATA = "update";
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//Toast.makeText(context, "Service Started in onStartCommand", Toast.LENGTH_LONG).show();
if(intent.getAction().equals(UPDATE_DATA)){
Toast.makeText(context, "Service Started in onStartCommand", Toast.LENGTH_LONG).show();
//getandcheck();
}
return START_STICKY;
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
public void getandcheck(){
//getting the values from server
gs1 = new GetFromServer();
gs1.sendData();
gs1.setArray();
//setting variables to latest sensor values
temperature = gs1.Temperature[0];
humidity = gs1.Humidity[0];
pressure = gs1.Pressure[0];
light = gs1.Ambient[0];
record.open();
//making function calls to setup flags
checktemp();
checkhum();
checkpress();
checklight();
//if any flag is true the it means that readings are out of range
if(tempflag == true){
String readings = ("Temperature : " + temperature +" °C");
final Notification.Builder builder = new Notification.Builder(service.this);
builder.setStyle(new Notification.BigTextStyle(builder)
.bigText(readings)
.setBigContentTitle("WSstation")
.setSummaryText("Alert!!!"))
.setContentTitle("WSstation")
.setContentText("Your Temperature Readings are out of range")
.setSmallIcon(R.drawable.auicon);
final NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify(0, builder.build());
}
if(pressflag == true){
String readings = ("Pressure : " + pressure +" hpa");
final Notification.Builder builder = new Notification.Builder(service.this);
builder.setStyle(new Notification.BigTextStyle(builder)
.bigText(readings)
.setBigContentTitle("WSstation")
.setSummaryText("Alert!!!"))
.setContentTitle("WSstation")
.setContentText("Your Pressure Readings are out of range")
.setSmallIcon(R.drawable.auicon);
final NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify(0, builder.build());
}
if(humflag == true){
String readings = ("Humidity : " + humidity +" %");
final Notification.Builder builder = new Notification.Builder(service.this);
builder.setStyle(new Notification.BigTextStyle(builder)
.bigText(readings)
.setBigContentTitle("WSstation")
.setSummaryText("Alert!!!"))
.setContentTitle("WSstation")
.setContentText("Your Humidity Readings are out of range")
.setSmallIcon(R.drawable.auicon);
final NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify(0, builder.build());
}
if(lightflag == true){
String readings = ("Ambient Light : " + light +" lx");
final Notification.Builder builder = new Notification.Builder(service.this);
builder.setStyle(new Notification.BigTextStyle(builder)
.bigText(readings)
.setBigContentTitle("WSstation")
.setSummaryText("Alert!!!"))
.setContentTitle("WSstation")
.setContentText("Your Ambient Light Readings are out of range")
.setSmallIcon(R.drawable.auicon);
final NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify(0, builder.build());
}
}
public void checktemp(){
//for temperature checking
value = record.getMax(1);
max = Double.parseDouble(value);
value = record.getMin(1);
min = Double.parseDouble(value);
if((temperature < min ) || (temperature > max)){
tempflag = true;
}
else{
tempflag = false;
}
}
public void checkhum(){
//for humidity checking
value = record.getMax(3);
max = Double.parseDouble(value);
value = record.getMin(3);
min = Double.parseDouble(value);
if((humidity < min ) || (humidity > max)){
humflag = true;
}
else{
humflag = false;
}
}
public void checkpress(){
//for pressure checking
value = record.getMax(2);
max = Double.parseDouble(value);
value = record.getMin(2);
min = Double.parseDouble(value);
if((pressure < min ) || (pressure > max)){
pressflag = true;
}
else{
pressflag = false;
}
}
public void checklight(){
//for ambient light checking
value = record.getMax(4);
max = Double.parseDouble(value);
value = record.getMin(4);
min = Double.parseDouble(value);
if((light < min ) || (light > max)){
lightflag = true;
}
else{
lightflag = false;
}
}
/*#Override
public void onCreate() {
super.onCreate();
Toast.makeText(context, "Service Started in oncreate", Toast.LENGTH_LONG).show();
}*/
}
content_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="slide.apptech.com.nav.MainActivity"
tools:showIn="#layout/app_bar_main">
<RelativeLayout
android:id="#+id/mainContent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#004D40">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:background="#004D40"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".Home"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true">
<!--<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="25dp"
android:textStyle="bold"
android:text=" Computer Languages..." />
-->
<ListView
android:paddingTop="60dp"
android:id="#+id/listView"
android:layout_width="fill_parent"
android:layout_height="376dp"
android:layout_above="#+id/datentime">
</ListView>
<TextView
android:paddingTop="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="Updated:"
android:textColor="#FFEB3B"
android:id="#+id/datentime"
android:layout_gravity="center_horizontal" />
<Button
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Refresh"
android:id="#+id/refresh"
android:layout_gravity="center_horizontal"
android:onClick="startService"/>
</LinearLayout>
</RelativeLayout>
</RelativeLayout>
logcat
04-20 20:15:18.623 27500-27500/slide.apptech.com.nav E/MotionRecognitionManager: mSContextService = null
04-20 20:15:18.628 27500-27500/slide.apptech.com.nav E/MotionRecognitionManager: motionService = com.samsung.android.motion.IMotionRecognitionService$Stub$Proxy#28c858d
04-20 20:15:24.578 27500-27500/slide.apptech.com.nav E/AndroidRuntime: FATAL EXCEPTION: main
Process: slide.apptech.com.nav, PID: 27500
java.lang.RuntimeException: Unable to start service slide.apptech.com.nav.service#1aa1fa82 with Intent { cmp=slide.apptech.com.nav/.service }: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3978)
at android.app.ActivityThread.access$2300(ActivityThread.java:211)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1803)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6912)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference
at slide.apptech.com.nav.service.onStartCommand(service.java:33)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3961)
at android.app.ActivityThread.access$2300(ActivityThread.java:211)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1803)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6912)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)
The intent you are checking in service.onStartCommand does not have an action. Change this
if(intent.getAction().equals(UPDATE_DATA)){
Toast.makeText(context, "Service Started in onStartCommand", Toast.LENGTH_LONG).show();
//getandcheck();
}
into this
if(intent.getAction() != null && intent.getAction().equals(UPDATE_DATA)){
Toast.makeText(context, "Service Started in onStartCommand", Toast.LENGTH_LONG).show();
//getandcheck();
}
UPDATE
To still show the toast you could put an extra boolean in your intent and check for this in your service. Start your service like this
startService(new Intent(getBaseContext(),service.class).putExtra("show_toast", true));
And check for it in your service like this
if (intent.getBooleanExtra("show_toast", false)) {
Toast.makeText(context, "Service Started in onStartCommand", Toast.LENGTH_LONG).show();
//getandcheck();
}
Looks like you didn't specify an action for the intent and you are getting a null pointer because of that.
Also be sure that you check the String constant against the object value to avoid null pointer exceptions.
UPDATE_DATA.equals(intent.getAction())
Related
I am completely new to Android Studio and just learned Object-oriented programming. My project requires me to build something on open-source code. I added a new menu item to a menu and want to start another activity once the user clicks the menu item with id: plot. I followed a recipe on the internet but got an error with it. It said 'method call expected' which means Terminal Fragment may be a method. I got confused, as I thought it is a class(an activity). Could anyone give me instructions to start an activity (turn to the next page with a different activity) in this case? What will be the simplest way to do this? Much Appreciated.
I added this in onOptionsItemSelected(MenuItem item).
if (id == R.id.plot){
Intent intent = new Intent(TerminalFragment.this, MainActivity2.class);
startActivity(intent);
}
TerminalFragment.java (entire code)
package de.kai_morich.simple_bluetooth_le_terminal;
import android.app.Activity;
import android.app.AlertDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.text.Editable;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.method.ScrollingMovementMethod;
import android.text.style.ForegroundColorSpan;
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.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
public class TerminalFragment extends Fragment implements ServiceConnection, SerialListener {
private MenuItem menuItem;
private enum Connected { False, Pending, True }
private String deviceAddress;
private SerialService service;
private TextView receiveText;
private TextView sendText;
private TextUtil.HexWatcher hexWatcher;
private Connected connected = Connected.False;
private boolean initialStart = true;
private boolean hexEnabled = false;
private boolean pendingNewline = false;
private String newline = TextUtil.newline_crlf;
/*
* Lifecycle
*/
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
//Register with activity
// You must inform the system that your app bar fragment is participating in the population of the options menu.
// tells the system that your fragment would like to receive menu-related callbacks.
setRetainInstance(true);
deviceAddress = getArguments().getString("device");
}
#Override
public void onDestroy() {
if (connected != Connected.False)
disconnect();
getActivity().stopService(new Intent(getActivity(), SerialService.class));
super.onDestroy();
}
#Override
public void onStart() {
super.onStart();
if(service != null)
service.attach(this);
else
getActivity().startService(new Intent(getActivity(), SerialService.class)); // prevents service destroy on unbind from recreated activity caused by orientation change
}
#Override
public void onStop() {
if(service != null && !getActivity().isChangingConfigurations())
service.detach();
super.onStop();
}
#SuppressWarnings("deprecation") // onAttach(context) was added with API 23. onAttach(activity) works for all API versions
#Override
public void onAttach(#NonNull Activity activity) {
super.onAttach(activity);
getActivity().bindService(new Intent(getActivity(), SerialService.class), this, Context.BIND_AUTO_CREATE);
}
#Override
public void onDetach() {
try { getActivity().unbindService(this); } catch(Exception ignored) {}
super.onDetach();
}
#Override
public void onResume() {
super.onResume();
if(initialStart && service != null) {
initialStart = false;
getActivity().runOnUiThread(this::connect);
}
}
#Override
public void onServiceConnected(ComponentName name, IBinder binder) {
service = ((SerialService.SerialBinder) binder).getService();
service.attach(this);
if(initialStart && isResumed()) {
initialStart = false;
getActivity().runOnUiThread(this::connect);
}
}
#Override
public void onServiceDisconnected(ComponentName name) {
service = null;
}
/*
* UI
*/
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_terminal, container, false);
receiveText = view.findViewById(R.id.receive_text); // TextView performance decreases with number of spans
receiveText.setTextColor(getResources().getColor(R.color.colorRecieveText)); // set as default color to reduce number of spans
receiveText.setMovementMethod(ScrollingMovementMethod.getInstance());
sendText = view.findViewById(R.id.send_text);
hexWatcher = new TextUtil.HexWatcher(sendText);
hexWatcher.enable(hexEnabled);
sendText.addTextChangedListener(hexWatcher);
sendText.setHint(hexEnabled ? "HEX mode" : "");
View sendBtn = view.findViewById(R.id.send_btn);
sendBtn.setOnClickListener(v -> send(sendText.getText().toString()));
return view;
}
#Override
public void onCreateOptionsMenu(#NonNull Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_terminal, menu);
menu.findItem(R.id.hex).setChecked(hexEnabled);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.clear) {
receiveText.setText("");
return true;
} if (id == R.id.plot){
Intent intent = new Intent(TerminalFragment.this, MainActivity2.class);
startActivity(intent);
}else if (id == R.id.newline) {
String[] newlineNames = getResources().getStringArray(R.array.newline_names);
String[] newlineValues = getResources().getStringArray(R.array.newline_values);
int pos = java.util.Arrays.asList(newlineValues).indexOf(newline);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Newline");
builder.setSingleChoiceItems(newlineNames, pos, (dialog, item1) -> {
newline = newlineValues[item1];
dialog.dismiss();
});
builder.create().show();
return true;
} else if (id == R.id.hex) {
hexEnabled = !hexEnabled;
sendText.setText("");
hexWatcher.enable(hexEnabled);
sendText.setHint(hexEnabled ? "HEX mode" : "");
item.setChecked(hexEnabled);
return true;
} else {
return super.onOptionsItemSelected(item);
}
}
/*
* Serial + UI
*/
private void connect() {
try {
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
BluetoothDevice device = bluetoothAdapter.getRemoteDevice(deviceAddress);
status("connecting...");
connected = Connected.Pending;
SerialSocket socket = new SerialSocket(getActivity().getApplicationContext(), device);
service.connect(socket);
} catch (Exception e) {
onSerialConnectError(e);
}
}
private void disconnect() {
connected = Connected.False;
service.disconnect();
}
private void send(String str) {
if(connected != Connected.True) {
Toast.makeText(getActivity(), "not connected", Toast.LENGTH_SHORT).show();
return;
}
try {
String msg;
byte[] data;
if(hexEnabled) {
StringBuilder sb = new StringBuilder();
TextUtil.toHexString(sb, TextUtil.fromHexString(str));
TextUtil.toHexString(sb, newline.getBytes());
msg = sb.toString();
data = TextUtil.fromHexString(msg);
} else {
msg = str;
data = (str + newline).getBytes();
}
SpannableStringBuilder spn = new SpannableStringBuilder(msg + '\n');
spn.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.colorSendText)), 0, spn.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
receiveText.append(spn);
service.write(data);
} catch (Exception e) {
onSerialIoError(e);
}
}
private void receive(byte[] data) {
if(hexEnabled) {
receiveText.append("Hello" + TextUtil.toHexString(data) + '\n');
} else {
String msg = new String(data);
if(newline.equals(TextUtil.newline_crlf) && msg.length() > 0) {
// don't show CR as ^M if directly before LF
msg = msg.replace(TextUtil.newline_crlf, TextUtil.newline_lf);
// special handling if CR and LF come in separate fragments
if (pendingNewline && msg.charAt(0) == '\n') {
Editable edt = receiveText.getEditableText();
if (edt != null && edt.length() > 1)
edt.replace(edt.length() - 2, edt.length(), "");
}
pendingNewline = msg.charAt(msg.length() - 1) == '\r';
}
receiveText.append(TextUtil.toCaretString(msg, newline.length() != 0)); //print out data
}
}
private void status(String str) {
SpannableStringBuilder spn = new SpannableStringBuilder(str + '\n');
spn.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.colorStatusText)), 0, spn.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
receiveText.append(spn);
}
/*
* SerialListener
*/
#Override
public void onSerialConnect() {
status("connected");
connected = Connected.True;
}
#Override
public void onSerialConnectError(Exception e) {
status("connection failed: " + e.getMessage());
disconnect();
}
#Override
public void onSerialRead(byte[] data) {
receive(data);
}
#Override
public void onSerialIoError(Exception e) {
status("connection lost: " + e.getMessage());
disconnect();
}
}
menu_terminal.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/plot"
android:title="PLOTDATA"
app:showAsAction="always" />
<item
android:id="#+id/clear"
android:icon="#drawable/ic_delete_white_24dp"
android:title="Clear"
app:showAsAction="always" />
<item
android:id="#+id/newline"
android:title="Newline"
app:showAsAction="never" />
<item
android:id="#+id/hex"
android:title="HEX Mode"
android:checkable="true"
app:showAsAction="never" />
</menu>
Here, TerminalFragment is a fragment, not an activity. And so, instead of using TerminalFragment.this in new Intent(), you should use getActivity().
So, the final code would look something like this:
Intent intent = new Intent(getActivity(), MainActivity2.class);
startActivity(intent);
You can also check this: Intent from Fragment to Activity
The app crashes when I write mNavigationView.setNavigationItemSelectedListener(this); in the code
and if it is not added it removes the functionality of the item in the navigation bar. Which method I should run in a background thread to reduce the effect on the main thread.
import android.app.Activity;
import android.support.annotation.NonNull;
import android.support.design.widget.NavigationView;
import android.support.v4.widget.DrawerLayout;
import android.support.v4.widget.SwipeRefreshLayout;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.eggheadgames.aboutbox.AboutConfig;
import com.eggheadgames.aboutbox.IAnalytic;
import com.eggheadgames.aboutbox.IDialog;
import com.eggheadgames.aboutbox.activity.AboutActivity;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class EarthquakeActivity extends AppCompatActivity implements SharedPreferences.OnSharedPreferenceChangeListener, SwipeRefreshLayout.OnRefreshListener, LoaderManager.LoaderCallbacks<List<Earthquake>>, NavigationView.OnNavigationItemSelectedListener {
public static final String MyPrefs = "MyPrefs";
private DrawerLayout mdrawerlayout;
private ActionBarDrawerToggle mToogle;
/** URL for earthquake data from the USGS dataset */
private static final String USGS_REQUEST_URL = "https://earthquake.usgs.gov/fdsnws/event/1/query";
/**
* Constant value for the earthquake loader ID. We can choose any integer.
* This really only comes into play if you're using multiple loaders.
*/
private static final int EARTHQUAKE_LOADER_ID = 1;
/** Adapter for the list of earthquakes */
private EarthquakeAdapter mAdapter;
/** TextView that is displayed when the list is empty */
private TextView mEmptyStateTextView;
SwipeRefreshLayout swipe;
private static final String LOG_TAG = EarthquakeActivity.class.getSimpleName();
private ListView earthquakeListView;
private static final String TWITTER_USER_NAME = "vaibhav_khulbe";
private static final String WEB_HOME_PAGE = "https://about.me/vaibhav_khulbe";
private static final String APP_PUBLISHER = "https://play.google.com/store/apps/developer?id=Vaibhav%20Khulbe&hl=en";
private static final String EMAIL_ADDRESS = "khulbevaibhavdev#gmail.com";
private static final String EMAIL_SUBJECT = "Quake Info app acknowledgements and/or issues";
private static final String EMAIL_BODY = "Please explain your experience with this app here...This may include bugs" +
" or issues you may be facing or what you liked about the app along with improvements. :) (MAKE SURE to clear out these lines before sending the mail to us)";
Toolbar toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.earthquake_activity);
mdrawerlayout=(DrawerLayout)findViewById(R.id.drawer);
mToogle=new ActionBarDrawerToggle(this,mdrawerlayout,R.string.open,R.string.close);
mdrawerlayout.addDrawerListener(mToogle);
mToogle.syncState();
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
NavigationView mNavigationView=(NavigationView)findViewById(R.id.navigation_view);
mNavigationView.setNavigationItemSelectedListener(this);
swipe = findViewById(R.id.swiperefresh);
swipe.setOnRefreshListener(this);
swipe.setColorSchemeColors(getResources().getColor(R.color.colorAccent));
/* Start the intro only once */
SharedPreferences sp = getSharedPreferences(MyPrefs, Context.MODE_PRIVATE);
if (!sp.getBoolean("first", false)) {
SharedPreferences.Editor editor = sp.edit();
editor.putBoolean("first", true);
editor.apply();
Intent intent = new Intent(this, IntroActivity.class);
startActivity(intent);
}
//Call and launch About activity
initAboutActivity();
// Find a reference to the {#link ListView} in the layout
earthquakeListView = (ListView) findViewById(R.id.list);
mEmptyStateTextView = (TextView) findViewById(R.id.empty_view);
earthquakeListView.setEmptyView(mEmptyStateTextView);
// Create a new adapter that takes an empty list of earthquakes as input
mAdapter = new EarthquakeAdapter(this, new ArrayList<Earthquake>());
// Set the adapter on the {#link ListView}
// so the list can be populated in the user interface
earthquakeListView.setAdapter(mAdapter);
// Obtain a reference to the SharedPreferences file for this app
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
// And register to be notified of preference changes
// So we know when the user has adjusted the query settings
prefs.registerOnSharedPreferenceChangeListener(this);
// Set an item click listener on the ListView, which sends an intent to a web browser
// to open a website with more information about the selected earthquake.
earthquakeListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
// Find the current earthquake that was clicked on
Earthquake currentEarthquake = mAdapter.getItem(position);
// Convert the String URL into a URI object (to pass into the Intent constructor)
Uri earthquakeUri = Uri.parse(currentEarthquake.getUrl());
// Create a new intent to view the earthquake URI
Intent websiteIntent = new Intent(Intent.ACTION_VIEW, earthquakeUri);
// Send the intent to launch a new activity
startActivity(websiteIntent);
}
});
getSupportLoaderManager().initLoader(EARTHQUAKE_LOADER_ID, null, this);
}
/*Code to launch About activity */
public void initAboutActivity()
{
/* Create About activity */
AboutConfig aboutConfig = AboutConfig.getInstance();
aboutConfig.appName = getString(R.string.app_name);
aboutConfig.appIcon = R.mipmap.ic_launcher;
aboutConfig.version = "1.0.0";
aboutConfig.author = "Vaibhav Khulbe";
aboutConfig.aboutLabelTitle = "About";
aboutConfig.packageName = getApplicationContext().getPackageName();
aboutConfig.appPublisher = APP_PUBLISHER;
aboutConfig.twitterUserName = TWITTER_USER_NAME;
aboutConfig.webHomePage = WEB_HOME_PAGE;
aboutConfig.dialog = new IDialog() {
#Override
public void open(AppCompatActivity appCompatActivity, String url, String tag) {
// handle custom implementations of WebView. It will be called when user click to web items. (Example: "Privacy", "Acknowledgments" and "About")
}
};
aboutConfig.analytics = new IAnalytic() {
#Override
public void logUiEvent(String s, String s1) {
// handle log events.
}
#Override
public void logException(Exception e, boolean b) {
// handle exception events.
}
};
// set it only if aboutConfig.analytics is defined.
aboutConfig.logUiEventName = "Log";
// Contact Support email details
aboutConfig.emailAddress = EMAIL_ADDRESS;
aboutConfig.emailSubject = EMAIL_SUBJECT;
aboutConfig.emailBody = EMAIL_BODY;
aboutConfig.shareMessage = getString(R.string.share_message);
aboutConfig.sharingTitle = getString(R.string.sharing_title);
}
#Override
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
if (key.equals(getString(R.string.settings_min_magnitude_key)) ||
key.equals(getString(R.string.settings_order_by_key))){
// Clear the ListView as a new query will be kicked off
mAdapter.clear();
// Hide the empty state text view as the loading indicator will be displayed
mEmptyStateTextView.setVisibility(View.GONE);
// Show the loading indicator while new data is being fetched
View loadingIndicator = findViewById(R.id.loading_indicator);
loadingIndicator.setVisibility(View.VISIBLE);
// Restart the loader to requery the USGS as the query settings have been updated
getSupportLoaderManager().restartLoader(EARTHQUAKE_LOADER_ID, null, this);
}
}
#Override
public Loader<List<Earthquake>> onCreateLoader(int i, Bundle bundle) {
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
String minMagnitude = sharedPrefs.getString(
getString(R.string.settings_min_magnitude_key),
getString(R.string.settings_min_magnitude_default));
String orderBy = sharedPrefs.getString(
getString(R.string.settings_order_by_key),
getString(R.string.settings_order_by_default)
);
String region = sharedPrefs.getString(
getString(R.string.settings_narrow_by_region_key),
getString(R.string.settings_narrow_by_region_default)
);
String radius = sharedPrefs.getString(
getString(R.string.settings_maximum_radius_key),
getString(R.string.settings_maximum_radius_default)
);
List<Country> countries = new ArrayList<>();
try {
countries = Utils.generateCountryList(this);
} catch (IOException e) {
e.printStackTrace();
}
Double latitude = 0.0;
Double longitude = 0.0;
for (Country country : countries) {
if(country.getName().equalsIgnoreCase(region)){
latitude = country.getLatitude();
longitude = country.getLongitude();
}
}
Uri baseUri = Uri.parse(USGS_REQUEST_URL);
Uri.Builder uriBuilder = baseUri.buildUpon();
uriBuilder.appendQueryParameter("format", "geojson");
uriBuilder.appendQueryParameter("limit", "100");
uriBuilder.appendQueryParameter("minmag", minMagnitude);
uriBuilder.appendQueryParameter("orderby", orderBy);
if(latitude != 0.0 && longitude != 0.0){
uriBuilder.appendQueryParameter("latitude", String.valueOf(latitude.intValue()));
uriBuilder.appendQueryParameter("longitude", String.valueOf(longitude.intValue()));
uriBuilder.appendQueryParameter("maxradius", radius);
}
String url = uriBuilder.toString();
return new EarthquakeLoader(this, url);
}
#Override
public void onLoadFinished(Loader<List<Earthquake>> loader, List<Earthquake> earthquakes) {
swipe.setRefreshing(false);
// Hide loading indicator because the data has been loaded
View loadingIndicator = findViewById(R.id.loading_indicator);
loadingIndicator.setVisibility(View.GONE);
if (earthquakes != null && !earthquakes.isEmpty()) {
this.showResults(earthquakes);
} else {
this.hideResults();
}
}
#Override
public void onLoaderReset(Loader<List<Earthquake>> loader) {
// Loader reset, so we can clear out our existing data.
mAdapter.clear();
}
/**
* method to show results
*/
private void showResults(List<Earthquake> earthquakeList) {
mAdapter.clear();
earthquakeListView.setVisibility(View.VISIBLE);
mEmptyStateTextView.setVisibility(View.GONE);
mAdapter.setNotifyOnChange(false);
mAdapter.setNotifyOnChange(true);
mAdapter.addAll(earthquakeList);
}
/**
* method to hide results also checks internet connection
*/
private void hideResults() {
earthquakeListView.setVisibility(View.GONE);
mEmptyStateTextView.setVisibility(View.VISIBLE);
// Get a reference to the ConnectivityManager to check state of network connectivity
ConnectivityManager connMgr = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
// Get details on the currently active default data network
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
mEmptyStateTextView.setText(R.string.no_earthquakes);
Log.e(LOG_TAG, "no earthquakes data");
} else {
mEmptyStateTextView.setText(R.string.no_internet_connection);
Log.e(LOG_TAG, "no internet");
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (mToogle.onOptionsItemSelected(item)){
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onRefresh() {
getSupportLoaderManager().restartLoader(EARTHQUAKE_LOADER_ID, null, this);
Toast.makeText(this, R.string.list_refreshed, Toast.LENGTH_SHORT).show();
}
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
Intent settingsIntent = new Intent(this, SettingsActivity.class);
startActivity(settingsIntent);
return true;
}
if (id == R.id.action_about) {
Intent actionIntent = new Intent(this, AboutActivity.class);
startActivity(actionIntent);
return true;
}
if (id == R.id.action_did_you_feel_it){
Intent feelItIntent = new Intent(this, DidYouFeel.class);
startActivity(feelItIntent);
return true;
}
if (id == R.id.action_more_apps){
Uri uri = Uri.parse( "https://play.google.com/store/apps/developer?id=Vaibhav+Khulbe" );
startActivity( new Intent( Intent.ACTION_VIEW, uri ) );
}
if (id == R.id.fork_project){
Uri uri = Uri.parse( "https://github.com/Kvaibhav01/Quake-Info" );
startActivity( new Intent( Intent.ACTION_VIEW, uri ) );
}
if (id == R.id.notification){
Intent notificationIntent = new Intent(this, EarthquakeNotification.class);
startActivity(notificationIntent);
}
return true;
}
}
I think it can be done by running the method in a background thread but I am not sure how to do that. Thanks for helping
you can use sample code like this:
((MainActivity)context).runOnUiThread(new Runnable() {
public void run() {
//run another thread
}
});
or if you are familiar with RxJava you can use it.
consider that most of the time you should perform a function that you will call it after the click, not the click method.
I'm new to Android development.
Recently I wanted to make an app which First Activity calculates a number and sends it through an intent to the Second activity.
So far so good.
But in this stage I'm facing some problem.
That is, when I receive the intent via getIntent(), it is OK.
But I don't know how do I save the getIntent() value in a SQLite database?
Hope you guys will help me to fix this problem.
This is my First Activity
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdView;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class DrinkActivity extends AppCompatActivity {
// Remove the below line after defining your own ad unit ID.
//private static final String TOAST_TEXT = "Test ads are being shown. "
// + "To show live ads, replace the ad unit ID in res/values/strings.xml with your own ad unit ID.";
//this is how many count
int a = 0;
//this is hoq much
int b = 0;
//this is button who is send information and go next page
Button B1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_drink);
// Load an ad into the AdMob banner view.
AdView adView = (AdView) findViewById(R.id.adView);
AdRequest adRequest = new AdRequest.Builder()
.setRequestAgent("android_studio:ad_template").build();
adView.loadAd(adRequest);
// Toasts the test ad message on the screen. Remove this after defining your own ad unit ID.
//Toast.makeText(this, TOAST_TEXT, Toast.LENGTH_LONG).show();
B1 = (Button) findViewById(R.id.gonextPage);
B1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(DrinkActivity.this,ScrollingActivity.class);
int x = a ;
int y = b;
int z = a * b;
intent.putExtra("drinkhowmany",x);
intent.putExtra("drinkhowmuch",y);
intent.putExtra("drinktotal",z);
startActivity(intent);
}
});
}
//this method count down how many drink plus calculation
public void howmanyPlusButton(View view){
if (a == 100){
return;
}
a = a + 1;
displayHowMany(a);
}
//this method count down how many drink minus calculation
public void howmanyMinusButton(View view){
if (a == -0){
return;
}
a = a - 1;
displayHowMany(a);
}
//this method count down how much price drink plus calculation
public void howmuchPlusButton(View view){
if (b == 100){
return;
}
b = b +1;
displayHowMuch(b);
}
//this method count down how much price minus drink calculation
public void howmuchMinusButton(View view){
if (b == -0){
return;
}
b = b -1;
displayHowMuch(b);
}
//this text show user how many digit
private void displayHowMany(int i){
TextView textView = (TextView) findViewById(R.id.howMany);
textView.setText(""+i);
}
//this text show user how much price digit
private void displayHowMuch(int i){
TextView textView = (TextView) findViewById(R.id.howMuch);
textView.setText("$"+i);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_drink, menu);
return true;
}
#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);
}
}
This is my 2nd Activity
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class ScrollingActivity extends AppCompatActivity {
//drink text working hear
TextView drinkhowmany,drinkhowmuch,drinktotal;
//data save button and data delete button
Button save,delete;
//database
SQLiteDataBase sqLiteDataBase;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scrolling);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
Intent intent = new Intent(ScrollingActivity.this,MenuActivity.class);
startActivity(intent);
}
});
//main text working and shoq user preview hear
//database call hear
sqLiteDataBase = new SQLiteDataBase(this);
//this is drink section
//this is show user hoq many drink user order
drinkhowmany = (TextView) findViewById(R.id.drinkHowMany);
drinkhowmany.setText(""+getIntent().getIntExtra("drinkhowmany",0));
//thisis show user how much drink price
drinkhowmuch = (TextView) findViewById(R.id.drinkHowMuch);
drinkhowmuch.setText("$"+getIntent().getIntExtra("drinkhowmuch",0));
//this is show user total drink price
final int drinkTotalInt = +getIntent().getIntExtra("drinktotal",0);
drinktotal = (TextView) findViewById(R.id.drinkTotal);
drinktotal.setText("$"+drinkTotalInt);
//buttton with database
save = (Button) findViewById(R.id.savedataButton);
save.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
boolean chaker = saveDataFile.addtoTable(`what i need to write hear also ?` );
if (chaker == true){
Toast.makeText(getBaseContext(),"SAVE YOUR DATA",Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(getBaseContext(),"Your Data Not Save",Toast.LENGTH_SHORT).show();
}
}
});
}
}
SQLITE ACTIVITY
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
/**
* Created by AIB Nihan on 10/4/2016.
*/
public class SQLiteDataBase extends SQLiteOpenHelper {
//this is the like box of information this is the box of which user input ther value
private static final String DATABASE_NAME = "mydatabase.db";
private static final String TABLE_NAME = "mytable";
private static final String DRINK_PRICE = "drink";
public SQLiteDataBase(Context context) {
super(context, DATABASE_NAME, null, 1);
}
#Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
String query;
query = "CREATE TABLE " +TABLE_NAME+ "(" +CIG_PRICE+ " INTEGER, "+ ")";
sqLiteDatabase.execSQL(query);
}
#Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
sqLiteDatabase.execSQL(" DROP FILE IF EXITS " + TABLE_NAME);
onCreate(sqLiteDatabase);
}
//int coffee,,int drink,int food,int other
public boolean addtotable(int cig){
SQLiteDatabase sqLiteDatabase = getWritableDatabase();
ContentValues contentValues = new ContentValues();
//contentValues.put(DRINK_PRICE,drink);
long chaker = sqLiteDatabase.insert(TABLE_NAME,null,contentValues);
if (chaker == 1){
return false;
}else {
return true;
}
}
public Cursor display(){
SQLiteDatabase sqLiteDatabase = getReadableDatabase();
Cursor res = sqLiteDatabase.rawQuery("SELECT * FORM" + TABLE_NAME,null);
return res;
}
}
As per your code , You can pass integer to addtotable() by passing drinkTotalInt or some integer value.
e.g
save.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) { boolean chaker =
saveDataFile.addtoTable(drinkTotalIn); if (chaker == true){
Toast.makeText(getBaseContext(),"SAVE YOUR
DATA",Toast.LENGTH_SHORT).show(); }else {
Toast.makeText(getBaseContext(),"Your Data Not
Save",Toast.LENGTH_SHORT).show();
}
}
});
and in addtable() insert passing value as below,
contentValues.put(DRINK_PRICE, [insert data]);
If You want to insert intent into sqlite, change sqlite schema as:
query = "CREATE TABLE " +TABLE_NAME+ "(" +CIG_PRICE+ " **TEXT**, "+ ")";
then, pass intent as argument to addtable().
e.g ,
addtable(getIntent());
In addtable():
public boolean addtotable(Intent intent){
SQLiteDatabase sqLiteDatabase = getWritableDatabase();
ContentValues contentValues = new ContentValues();
String intentDescription = intent.toUri(0);
contentValues.put(DRINK_PRICE,intentDescription);
long chaker = sqLiteDatabase.insert(TABLE_NAME,null,contentValues);
if (chaker == 1){
return false;
}else {
return true;
}
}
Get intent from sqlite:
String intentDescription = cursor.getString(intentIndex);
Intent intent = Intent.parseUri(intentDescription, 0);
Now you can parse intent to get all values.
Edit:
Getting intent from sqlite in more details:
SQLiteDatabase sqLiteDatabase = getWritableDatabase();
Cursor cursor = sqLiteDatabase .rawQuery("select * from [table-name] ");
if (cursor.moveToFirst()) {
do {
String intentDescription = cursor.getString(0); // getting intent from sqlite at index 0
Intent intent = Intent.parseUri(intentDescription, 0);
} while (cursor.moveToNext());
}
if (cursor != null && !cursor.isClosed()) {
cursor.close();
}
if(db!=null)
{
db.close();
}
You will need to use ContentValues.
I would recommend using this tutorial:
https://www.tutorialspoint.com/android/android_sqlite_database.htm
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 7 years ago.
I'm trying to implement DropDownMenu https://github.com/JayFang1993/DropDownMenu
I've got a problem with this code :
MainActivity
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.util.TypedValue;
import android.view.Menu;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import com.jayfang.dropdownmenu.DropDownMenu;
import com.jayfang.dropdownmenu.OnMenuSelectedListener;
import com.oguzdev.circularfloatingactionmenu.library.FloatingActionButton;
import com.oguzdev.circularfloatingactionmenu.library.FloatingActionMenu;
import com.oguzdev.circularfloatingactionmenu.library.SubActionButton;
import com.sai.eventee.rss.ServiceStarter;
import com.sai.eventee.util.ScrimInsetsFrameLayout;
import com.sai.eventee.web.WebviewFragment;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity implements
NavDrawerCallback {
private Toolbar mToolbar;
private NavDrawerFragment mNavigationDrawerFragment;
public static String DATA = "transaction_data";
public static String EMBEDD_DATA = "embedd";
SharedPreferences prefs;
boolean openedByBackPress = false;
//=======================================================
private DropDownMenu mMenu;
private ListView mList;
private int city_index;
private int sex_index;
private int age_index;
private List<String> data;
final String[] arr1=new String[]{"全部城市","北京","上海","广州","深圳"};
final String[] arr2=new String[]{"性别","男","女"};
final String[] arr3=new String[]{"全部年龄","10","20","30","40","50","60","70"};
final String[] strings=new String[]{"选择城市","选择性别","选择年龄"};
private FloatingActionButton mFAB;
private FloatingActionMenu mFABMenu;
//=======================================================
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setupFAB();
boolean newDrawer = getResources().getBoolean(R.bool.newdrawer);
if (newDrawer == true) {
setContentView(R.layout.activity_main_alternate);
} else {
setContentView(R.layout.activity_main);
Helper.setStatusBarColor(MainActivity.this, getResources()
.getColor(R.color.myPrimaryDarkColor));
}
mMenu=(DropDownMenu)findViewById(R.id.menu);
mMenu.setmMenuCount(3);
mMenu.setmShowCount(6);
mMenu.setShowCheck(true);
mMenu.setmMenuTitleTextSize(16);
mMenu.setmMenuTitleTextColor(Color.parseColor("#777777"));
mMenu.setmMenuListTextSize(16);
mMenu.setmMenuListTextColor(Color.BLACK);
mMenu.setmMenuBackColor(Color.parseColor("#eeeeee"));
mMenu.setmMenuPressedBackColor(Color.WHITE);
mMenu.setmMenuPressedTitleTextColor(Color.BLACK);
mMenu.setmCheckIcon(R.drawable.ico_make);
mMenu.setmUpArrow(R.drawable.arrow_up);
mMenu.setmDownArrow(R.drawable.arrow_down);
mMenu.setDefaultMenuTitle(strings);
mMenu.setShowDivider(false);
mMenu.setmMenuListBackColor(getResources().getColor(R.color.white));
mMenu.setmMenuListSelectorRes(R.color.white);
mMenu.setmArrowMarginTitle(20);
mMenu.setMenuSelectedListener(new OnMenuSelectedListener() {
#Override
public void onSelected(View listview, int RowIndex, int ColumnIndex) {
Log.i("MainActivity", "select " + ColumnIndex + " column and " + RowIndex + " row");
if (ColumnIndex == 0) {
city_index = RowIndex;
} else if (ColumnIndex == 1) {
sex_index = RowIndex;
} else {
age_index = RowIndex;
}
//过滤筛选
setFilter();
}
});
List<String[]> items = new ArrayList<>();
items.add(arr1);
items.add(arr2);
items.add(arr3);
mMenu.setmMenuItems(items);
mMenu.setIsDebug(false);
mList=(ListView)findViewById(R.id.lv_list);
data=getData();
mList.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1, data));
mToolbar = (Toolbar) findViewById(R.id.toolbar_actionbar);
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayShowHomeEnabled(true);
mNavigationDrawerFragment = (NavDrawerFragment) getSupportFragmentManager()
.findFragmentById(R.id.fragment_drawer);
if (newDrawer == true) {
mNavigationDrawerFragment.setup(R.id.scrimInsetsFrameLayout,
(DrawerLayout) findViewById(R.id.drawer), mToolbar);
mNavigationDrawerFragment
.getDrawerLayout()
.setStatusBarBackgroundColor(
getResources().getColor(R.color.myPrimaryDarkColor));
((ScrimInsetsFrameLayout) findViewById(R.id.scrimInsetsFrameLayout)).getLayoutParams().width = getDrawerWidth();
} else {
mNavigationDrawerFragment.setup(R.id.fragment_drawer,
(DrawerLayout) findViewById(R.id.drawer), mToolbar);
DrawerLayout.LayoutParams params = (android.support.v4.widget.DrawerLayout.LayoutParams) mNavigationDrawerFragment.getView().getLayoutParams();
params.width = getDrawerWidth();
mNavigationDrawerFragment.getView().setLayoutParams(params);
}
prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
// setting push enabled
String push = getString(R.string.rss_push_url);
if (null != push && !push.equals("")) {
// Create object of SharedPreferences.
boolean firstStart = prefs.getBoolean("firstStart", true);
if (firstStart) {
final ServiceStarter alarm = new ServiceStarter();
SharedPreferences.Editor editor = prefs.edit();
alarm.setAlarm(this);
// now, just to be sure, where going to set a value to check if
// notifications is really enabled
editor.putBoolean("firstStart", false);
// commits your edits
editor.commit();
}
}
// Checking if the user would prefer to show the menu on start
boolean checkBox = prefs.getBoolean("menuOpenOnStart", false);
if (checkBox == true) {
mNavigationDrawerFragment.openDrawer();
}
// New imageloader
Helper.initializeImageLoader(this);
}
private void setFilter(){
List<String> temp=new ArrayList<String>();
for (int i=0;i<getData().size();i++){
boolean city=((city_index==0)?true:data.get(i).contains(arr1[city_index]));
boolean sex=((sex_index==0)?true:data.get(i).contains(arr2[sex_index]));
boolean age=((age_index==0)?true:data.get(i).contains(arr3[age_index]));
if(city && sex && age){
temp.add(data.get(i));
}
}
mList.setAdapter(new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_expandable_list_item_1,temp));
}
private List<String> getData(){
List<String> data = new ArrayList<String>();
data.add("上海-男-10");
data.add("上海-男-20");
data.add("上海-男-30");
data.add("上海-男-40");
data.add("上海-男-50");
data.add("上海-男-60");
data.add("上海-男-70");
data.add("广州-男-10");
data.add("广州-女-10");
data.add("北京-男-20");
data.add("北京-女-10");
data.add("广州-男-10");
data.add("北京-男-10");
data.add("广州-男-10");
data.add("上海-女-60");
data.add("上海-女-20");
return data;
}
private void setupFAB() {
//define the icon for the main floating action button
ImageView iconFAB = new ImageView(this);
iconFAB.setImageResource(R.drawable.ic_action_new);
//set the appropriate background for the main floating action button along with its icon
mFAB = new FloatingActionButton.Builder(this)
.setContentView(iconFAB)
.setBackgroundDrawable(R.drawable.selector_button_red)
.build();
//define the icons for the sub action buttons
ImageView iconSortName = new ImageView(this);
iconSortName.setImageResource(R.drawable.ic_action_alphabets);
ImageView iconSortDate = new ImageView(this);
iconSortDate.setImageResource(R.drawable.ic_action_calendar);
ImageView iconSortRatings = new ImageView(this);
iconSortRatings.setImageResource(R.drawable.ic_action_important);
//set the background for all the sub buttons
SubActionButton.Builder itemBuilder = new SubActionButton.Builder(this);
itemBuilder.setBackgroundDrawable(getResources().getDrawable(R.drawable.selector_sub_button_gray));
//build the sub buttons
SubActionButton buttonSortName = itemBuilder.setContentView(iconSortName).build();
SubActionButton buttonSortDate = itemBuilder.setContentView(iconSortDate).build();
SubActionButton buttonSortRatings = itemBuilder.setContentView(iconSortRatings).build();
/*
//to determine which button was clicked, set Tags on each button
buttonSortName.setTag(TAG_SORT_NAME);
buttonSortDate.setTag(TAG_SORT_DATE);
buttonSortRatings.setTag(TAG_SORT_RATINGS);
buttonSortName.setOnClickListener(this);
buttonSortDate.setOnClickListener(this);
buttonSortRatings.setOnClickListener(this);
*/
//add the sub buttons to the main floating action button
mFABMenu = new FloatingActionMenu.Builder(this)
.addSubActionView(buttonSortName)
.addSubActionView(buttonSortDate)
.addSubActionView(buttonSortRatings)
.attachTo(mFAB)
.build();
}
//===============================================================================*/
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// getMenuInflater().inflate(R.menu.rss_menu, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public void onNavigationDrawerItemSelected(int position, NavItem item) {
Fragment fragment;
try {
fragment = item.getFragment().newInstance();
if (fragment != null) {
Bundle bundle = new Bundle();
String extra;
String license = getResources().getString(R.string.google_play_license);
// if item does not require purchase, or app has purchased, or license is null/empty (app has no in app purchases)
if (item.requiresPurchase() == true
&& !SettingsFragment.getIsPurchased(this)
&& null != license && !license.equals("")) {
fragment = new SettingsFragment();
extra = SettingsFragment.SHOW_DIALOG;
} else {
extra = item.getData();
}
bundle.putString(DATA, extra);
fragment.setArguments(bundle);
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.container, fragment).commit();
setTitle(item.getText());
if (null != MainActivity.this.getSupportActionBar()
&& null != MainActivity.this.getSupportActionBar()
.getCustomView()) {
MainActivity.this.getSupportActionBar().setDisplayOptions(
ActionBar.DISPLAY_SHOW_HOME
| ActionBar.DISPLAY_SHOW_TITLE);
}
} else {
// error in creating fragment
Log.e("MainActivity", "Error in creating fragment");
}
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
#Override
public void onBackPressed() {
Fragment webview = getSupportFragmentManager().findFragmentById(
R.id.container);
if (mNavigationDrawerFragment.isDrawerOpen()) {
mNavigationDrawerFragment.closeDrawer();
} else if (webview instanceof WebviewFragment) {
boolean goback = ((WebviewFragment) webview).canGoBack();
if (!goback)
super.onBackPressed();
} else {
super.onBackPressed();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
List<Fragment> fragments = getSupportFragmentManager().getFragments();
if (fragments != null) {
for (Fragment frag : fragments)
frag.onActivityResult(requestCode, resultCode, data);
}
}
private int getDrawerWidth(){
// Navigation Drawer layout width
int width = getResources().getDisplayMetrics().widthPixels;
TypedValue tv = new TypedValue();
int actionBarHeight;
if (getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true))
{
actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data,getResources().getDisplayMetrics());
} else {
actionBarHeight = 0;
}
int possibleMinDrawerWidth = width - actionBarHeight;
int maxDrawerWidth = getResources().getDimensionPixelSize(R.dimen.drawer_width);
return Math.min(possibleMinDrawerWidth, maxDrawerWidth);
}
}
Activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
android:id="#+id/toolbar_actionbar"
layout="#layout/toolbar_default"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<android.support.v4.widget.DrawerLayout
android:id="#+id/drawer"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/toolbar_actionbar">
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<com.jayfang.dropdownmenu.DropDownMenu
android:orientation="horizontal"
android:layout_width="fill_parent"
android:id="#+id/menu"
android:background="#color/ripple_material_dark"
android:layout_height="60dp"/>
<ListView
android:layout_width="fill_parent"
android:layout_below="#id/menu"
android:id="#+id/lv_list"
android:background="#ffffff"
android:layout_height="wrap_content"></ListView>
<!-- android:layout_marginTop="?android:attr/actionBarSize"-->
<fragment
android:id="#+id/fragment_drawer"
android:name="com.sai.eventee.NavDrawerFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
app:layout="#layout/drawer_fragment"
tools:layout="#layout/drawer_fragment" />
</android.support.v4.widget.DrawerLayout>
</RelativeLayout>
And Logcat:
10-04 22:48:47.884 27075-27075/com.sai.eventee E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.sai.eventee, PID: 27075
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.sai.eventee/com.sai.eventee.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.jayfang.dropdownmenu.DropDownMenu.setmMenuCount(int)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2493)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2555)
at android.app.ActivityThread.access$800(ActivityThread.java:176)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1437)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5576)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:955)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:750)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.jayfang.dropdownmenu.DropDownMenu.setmMenuCount(int)' on a null object reference
at com.sai.eventee.MainActivity.onCreate(MainActivity.java:90)
at android.app.Activity.performCreate(Activity.java:6005)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1111)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2446)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2555)
at android.app.ActivityThread.access$800(ActivityThread.java:176)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1437)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5576)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:955)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:750)
I have no idea why I get a null pointer exception.
It means that findViewById(R.id.activity_main_alternate) returns null for mMenu. Does your activity_main_alternate.xml have the R.id.menu view?
i m completely beginner in android developing and following the tutorial for sunshine app, while running the app it was supposed to display the detail on detailactivity but gives error. help me figure it out
mainactivity
package com.example.android.sunshine.app;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/** if (savedInstanceState == null){
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new ForecastFragment())
.commit();
}*/
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#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();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
forecastFragment
package com.example.android.sunshine.app;
import android.content.Intent;
import android.net.*;
import android.os.*;
import android.support.v4.app.*;
import android.text.format.*;
import android.util.*;
import android.view.*;
import android.widget.*;
import org.json.*;
import java.io.*;
import java.net.*;
import java.text.*;
import java.util.*;
/**
* Created by Nabahat on 7/8/2015.
*/
public class ForecastFragment extends Fragment {
List<String> mWeekForecast;
ArrayAdapter<String> mForecastAdapter = null;
public ForecastFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.forecastfragment, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_refresh) {
FetchWeatherTask weatherTask = new FetchWeatherTask();
weatherTask.execute("94043");
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
String[] forecastArray = {
"Today - Sunny - 88/63",
"Tomorrow - Foggy - 70/40",
"Weds - Cloudy - 72/63",
"Thurs - Asteroids - 75/65",
"Fri - Heavy Rain - 65/56",
"Sat - HELP TRAPPED IN WEATHERSTATION - 60/51",
"Sun - Sunny - 80/68"
};
List<String> weekForecast = new ArrayList<String>(
Arrays.asList(forecastArray));
mForecastAdapter = new ArrayAdapter<String>(
getActivity(),
R.layout.list_item_forecast,
R.id.list_item_forecast_textview,
weekForecast);
ListView listView = (ListView) rootView.findViewById(R.id.listview_forecast);
listView.setAdapter(mForecastAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
String forecast = mForecastAdapter.getItem(position);
Intent intent = new Intent(getActivity(), DetailActivity.class )
.putExtra(Intent.EXTRA_TEXT, forecast);
startActivity(intent);
}
});
return rootView;
}
public class FetchWeatherTask extends AsyncTask<String, Void, String[]> {
private final String LOG_TAG = FetchWeatherTask.class.getSimpleName();
/* The date/time conversion code is going to be moved outside the asynctask later,
* so for convenience we're breaking it out into its own method now.
*/
private String getReadableDateString(long time) {
// Because the API returns a unix timestamp (measured in seconds),
// it must be converted to milliseconds in order to be converted to valid date.
SimpleDateFormat shortenedDateFormat = new SimpleDateFormat("EEE MMM dd");
return shortenedDateFormat.format(time);
}
/**
* Prepare the weather high/lows for presentation.
*/
private String formatHighLows(double high, double low) {
// For presentation, assume the user doesn't care about tenths of a degree.
long roundedHigh = Math.round(high);
long roundedLow = Math.round(low);
String highLowStr = roundedHigh + "/" + roundedLow;
return highLowStr;
}
/**
* Take the String representing the complete forecast in JSON Format and
* pull out the data we need to construct the Strings needed for the wireframes.
* <p/>
* Fortunately parsing is easy: constructor takes the JSON string and converts it
* into an Object hierarchy for us.
*/
private String[] getWeatherDataFromJson(String forecastJsonStr, int numDays)
throws JSONException {
// These are the names of the JSON objects that need to be extracted.
final String OWM_LIST = "list";
final String OWM_WEATHER = "weather";
final String OWM_TEMPERATURE = "temp";
final String OWM_MAX = "max";
final String OWM_MIN = "min";
final String OWM_DESCRIPTION = "main";
JSONObject forecastJson = new JSONObject(forecastJsonStr);
JSONArray weatherArray = forecastJson.getJSONArray(OWM_LIST);
// OWM returns daily forecasts based upon the local time of the city that is being
// asked for, which means that we need to know the GMT offset to translate this data
// properly.
// Since this data is also sent in-order and the first day is always the
// current day, we're going to take advantage of that to get a nice
// normalized UTC date for all of our weather.
Time dayTime = new Time();
dayTime.setToNow();
// we start at the day returned by local time. Otherwise this is a mess.
int julianStartDay = Time.getJulianDay(System.currentTimeMillis(), dayTime.gmtoff);
// now we work exclusively in UTC
dayTime = new Time();
String[] resultStrs = new String[numDays];
for (int i = 0; i < weatherArray.length(); i++) {
// For now, using the format "Day, description, hi/low"
String day;
String description;
String highAndLow;
// Get the JSON object representing the day
JSONObject dayForecast = weatherArray.getJSONObject(i);
// The date/time is returned as a long. We need to convert that
// into something human-readable, since most people won't read "1400356800" as
// "this saturday".
long dateTime;
// Cheating to convert this to UTC time, which is what we want anyhow
dateTime = dayTime.setJulianDay(julianStartDay + i);
day = getReadableDateString(dateTime);
// description is in a child array called "weather", which is 1 element long.
JSONObject weatherObject = dayForecast.getJSONArray(OWM_WEATHER).getJSONObject(0);
description = weatherObject.getString(OWM_DESCRIPTION);
// Temperatures are in a child object called "temp". Try not to name variables
// "temp" when working with temperature. It confuses everybody.
JSONObject temperatureObject = dayForecast.getJSONObject(OWM_TEMPERATURE);
double high = temperatureObject.getDouble(OWM_MAX);
double low = temperatureObject.getDouble(OWM_MIN);
highAndLow = formatHighLows(high, low);
resultStrs[i] = day + " - " + description + " - " + highAndLow;
}
for (String s : resultStrs) {
Log.v(LOG_TAG, "Forecast entry: " + s);
}
return resultStrs;
}
#Override
protected String[] doInBackground(String... params) {
if (params.length == 0) {
return null;
}
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
String forecastJsonStr = null;
String format = "json";
String units = "metric";
int numDays = 7;
try {
final String FORECAST_BASE_URL =
"http://api.openweathermap.org/data/2.5/forecast/daily?";
final String QUERY_PARAM = "q";
final String FORMAT_PARAM = "mode";
final String UNITS_PARAM = "units";
final String DAYS_PARAM = "cnt";
Uri builtUri = Uri.parse(FORECAST_BASE_URL).buildUpon()
.appendQueryParameter(QUERY_PARAM, params[0])
.appendQueryParameter(FORMAT_PARAM, format)
.appendQueryParameter(UNITS_PARAM, units)
.appendQueryParameter(DAYS_PARAM, Integer.toString(numDays))
.build();
URL url = new URL(builtUri.toString());
Log.v(LOG_TAG, "Built URI " + builtUri.toString());
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
//urlConnection.setRequestProperty("API_KEY", "c84aeef73dfe54e9ec696154cfb89a5a");
urlConnection.setDoInput(true);
urlConnection.setRequestProperty("User-Agent", "Mozilla/5.0 ( compatible ) ");
urlConnection.setRequestProperty("Accept", "*/*");
urlConnection.setDoOutput(false);
urlConnection.connect();
InputStream inputStream = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
if (inputStream == null) {
return null;
}
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
buffer.append(line + "\n");
}
if (buffer.length() == 0) {
return null;
}
forecastJsonStr = buffer.toString();
Log.v(LOG_TAG, "Forecast JSON String: " + forecastJsonStr);
} catch (IOException e) {
Log.e(LOG_TAG, "Error ", e);
return null;
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
Log.e(LOG_TAG, "Error closing stream", e);
}
}
}
try {
return getWeatherDataFromJson(forecastJsonStr, numDays);
} catch (JSONException e) {
Log.e(LOG_TAG, e.getMessage(), e);
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String[] result) {
if (result != null) {
mForecastAdapter.clear();
for (String dayForecastStr : result) {
mForecastAdapter.add(dayForecastStr);
}
}
}
}
}
detail activity
package com.example.android.sunshine.app;
import android.content.Intent;
import android.support.v4.app.Fragment;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class DetailActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new DetailFragment()).commit();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_detail, menu);
return true;
}
#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();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public static class DetailFragment extends Fragment {
public DetailFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Intent intent = getActivity().getIntent();
View rootView = inflater.inflate(R.layout.fragment_detail, container, false);
if (intent != null && intent.hasExtra(Intent.EXTRA_TEXT)){
String forecastStr = intent.getStringExtra(Intent.EXTRA_TEXT);
((TextView) rootView.findViewById(R.id.detail_text))
.setText(forecastStr);
}
return rootView;
}
}
}
activitydetail.xml
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:id="#+id/fragment"
android:name="com.example.android.sunshine.app.DetailActivity$DetailFragment"
tools:layout="#layout/fragment_detail" android:layout_width="match_parent"
android:layout_height="match_parent" />
activitymain.xml
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/fragment"
android:name="com.example.android.sunshine.app.ForecastFragment"
tools:layout="#layout/fragment_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
fragmentdetail.xml
<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:paddingLeft="64dp"
android:paddingRight="64dp"
android:paddingTop="16dp"
android:paddingBottom="16dp"
tools:context="com.example.android.sunshine.app.DetailFragment">
<TextView
android:id="#+id/detail_text"
android:text="#string/hello_world"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
fragmentmain.xml
<FrameLayout
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:paddingLeft="64dp"
android:paddingRight="64dp"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context="com.example.sunshine.app.MainActivityFragment$PlaceholderFragment"
android:id="#+id/container">
<ListView
android:id="#+id/listview_forecast"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
logcat
android.support.v7.internal.widget.ActionBarOverlayLayout{bd47b46 V.E..... ... 0,0-0,0 #7f0c003e app:id/decor_content_parent}
07-09 22:24:29.820 12200-12200/com.example.android.sunshine.app D/FragmentManager﹕ android.support.v7.internal.widget.ContentFrameLayout{252c0107 V.E..... ... 0,0-0,0 #1020002 android:id/content}
07-09 22:24:29.820 12200-12200/com.example.android.sunshine.app D/FragmentManager﹕ android.widget.RelativeLayout{39c34c6e V.E..... ... 0,0-0,0 #7f0c004f app:id/fragment}
07-09 22:24:29.820 12200-12200/com.example.android.sunshine.app D/FragmentManager﹕ android.support.v7.widget.AppCompatTextView{e76c234 V.ED.... ... 0,0-0,0 #7f0c0050 app:id/detail_text}
07-09 22:24:29.820 12200-12200/com.example.android.sunshine.app D/FragmentManager﹕ android.support.v7.internal.widget.ActionBarContainer{3ff4b85d V.ED.... ... 0,0-0,0 #7f0c003f app:id/action_bar_container}
07-09 22:24:29.826 12200-12200/com.example.android.sunshine.app D/FragmentManager﹕ android.support.v7.widget.Toolbar{4d05d2 V.E..... ... 0,0-0,0 #7f0c0040 app:id/action_bar}
07-09 22:24:29.828 12200-12200/com.example.android.sunshine.app D/FragmentManager﹕ android.widget.TextView{2afda6a3 V.ED.... ... 0,0-0,0}
07-09 22:24:29.828 12200-12200/com.example.android.sunshine.app D/FragmentManager﹕ android.support.v7.internal.widget.ActionBarContextView{1bd7cda0 G.E..... ... 0,0-0,0 #7f0c0041 app:id/action_context_bar}
07-09 22:24:29.829 12200-12200/com.example.android.sunshine.app D/AndroidRuntime﹕ Shutting down VM
07-09 22:24:29.830 12200-12200/com.example.android.sunshine.app E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.android.sunshine.app, PID: 12200
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.android.sunshine.app/com.example.android.sunshine.app.DetailActivity}: java.lang.IllegalArgumentException: No view found for id 0x7f0c0051 (com.example.android.sunshine.app:id/container) for fragment DetailFragment{2a0c5022 #1 id=0x7f0c0051}
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2325)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2390)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5257)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Caused by: java.lang.IllegalArgumentException: No view found for id 0x7f0c0051 (com.example.android.sunshine.app:id/container) for fragment DetailFragment{2a0c5022 #1 id=0x7f0c0051}
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:947)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1138)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:740)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1501)
at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:551)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1236)
at android.app.Activity.performStart(Activity.java:6006)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2288)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2390)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5257)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
07-09 22:24:32.288 12200-12209/com.example.android.sunshine.app W/art﹕ Suspending all threads took: 70.244ms
07-09 22:24:40.045 12200-12209/com.example.android.sunshine.app W/art﹕ Suspending all threads took: 5.676ms
Your DetailActivity has the lines:
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new DetailFragment()).commit();
}
But your activity_detail.xml as you've posted doesn't have any id named container - in fact, it already has a Fragment directly in the layout. You should remove the lines from your DetailActivity's onCreate().
In activitydetail.xml change android:id="#+id/fragment" to android:"#+id/container"