I used a handler to get a GoogleMap from a support map fragment. I am literally lost and have been trying to fix it for days. The map loads fine but I am suspecting it is returning a null value. I know there may be some bad practices but that's not my problem. I tried it with an AsyncTask and Handler. I tested it on various mobile devices and did not use emulator. Here is my code where I removes some other imports, but they are there (It's obviously not the whole program):
import com.codexmalta.mytravelbuddy.R;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import android.support.v4.app.FragmentActivity;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
public class Itinerary extends FragmentActivity implements View.OnClickListener {
//Google Map
GoogleMap map;
byte choice;
protected ProgressDialog dialog;
CameraPosition cameraPosition;
Timer timer = new Timer();
LinearLayout[] l = new LinearLayout[10];
TextView[] time = new TextView[10];
TextView[] desc = new TextView[10];
TextView[] loc = new TextView[10];
double[] lat = new double[10];
double[] lng = new double[10];
MarkerOptions[] marker = new MarkerOptions[10];
//Get Itinerary
GetItinerary gi = new GetItinerary();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_starting_point);
choice = getIntent().getByteExtra("choice", choice);
//Methods
getMapFragment();
getLayouts();
getFields();
gi.main(choice);
fillFields();
removeExtraLayouts(gi.giveNumDay1(),gi.giveNumDay2());
getMap();
displayMarkers();
animateCamera();
}
SupportMapFragment fm = new SupportMapFragment();
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.starting_point, menu);
return true;
}
private void removeExtraMarkers(){
for(int i = 0; i < 10; i++){
if(lat[i] == 0 && lng[i] == 0){
marker[i].alpha(0);
}
}
}
private void displayMarkers(){
String[] s = new String[10];
for(int i = 0; i < 10; i++){
s[i] = (String) loc[i].getText();
map.addMarker(marker[i].position(new LatLng(lat[i], lng[1])).title(s[i])).setVisible(true);
}
}
public void getMapFragment(){
fm = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
}
Handler mHandler = new Handler();
public void getMap(){
mHandler.post(new Runnable() {
#Override
public void run() {
GoogleMap map = fm.getMap();
if (map != null) {
map.setMyLocationEnabled(true);
// INIT HERE
map.getUiSettings().setMyLocationButtonEnabled(false);
// ...
} else mHandler.post(this);
}
});
while(map == null){
map = fm.getMap();
if(map!= null)break;
}
}
private void removeExtraLayouts(int a, int b){
//Day One
switch(a){
case 5:
l[0].removeAllViews();
l[1].removeAllViews();
l[2].removeAllViews();
l[3].removeAllViews();
l[4].removeAllViews();
break;
case 4:
l[1].removeAllViews();
l[2].removeAllViews();
l[3].removeAllViews();
l[4].removeAllViews();
break;
case 3:
l[2].removeAllViews();
l[3].removeAllViews();
l[4].removeAllViews();
break;
case 2:
l[3].removeAllViews();
l[4].removeAllViews();
break;
case 1:
l[4].removeAllViews();
break;
}
//Day Two
switch(b){
case 5:
l[5].removeAllViews();
l[6].removeAllViews();
l[7].removeAllViews();
l[8].removeAllViews();
l[9].removeAllViews();
break;
case 4:
l[6].removeAllViews();
l[7].removeAllViews();
l[8].removeAllViews();
l[9].removeAllViews();
break;
case 3:
l[7].removeAllViews();
l[8].removeAllViews();
l[9].removeAllViews();
break;
case 2:
l[8].removeAllViews();
l[9].removeAllViews();
break;
case 1:
l[9].removeAllViews();
break;
}
}
private void getLayouts(){
l[0] = (LinearLayout)findViewById(R.id.a1);
l[0].setOnClickListener(this);
l[1] = (LinearLayout)findViewById(R.id.a2);
l[1].setOnClickListener(this);
l[2] = (LinearLayout)findViewById(R.id.a3);
l[2].setOnClickListener(this);
l[3] = (LinearLayout)findViewById(R.id.a4);
l[3].setOnClickListener(this);
l[4] = (LinearLayout)findViewById(R.id.a5);
l[4].setOnClickListener(this);
l[5] = (LinearLayout)findViewById(R.id.a6);
l[5].setOnClickListener(this);
l[6] = (LinearLayout)findViewById(R.id.a7);
l[6].setOnClickListener(this);
l[7] = (LinearLayout)findViewById(R.id.a8);
l[7].setOnClickListener(this);
l[8] = (LinearLayout)findViewById(R.id.a9);
l[8].setOnClickListener(this);
l[9] = (LinearLayout)findViewById(R.id.a10);
l[9].setOnClickListener(this);
}
private void getFields(){
time[0] = (TextView)findViewById(R.id.time1);
desc[0] = (TextView)findViewById(R.id.desc1);
loc[0] = (TextView)findViewById(R.id.loc1);
time[1] = (TextView)findViewById(R.id.time2);
desc[1] = (TextView)findViewById(R.id.desc2);
loc[1] = (TextView)findViewById(R.id.loc2);
time[2] = (TextView)findViewById(R.id.time3);
desc[2] = (TextView)findViewById(R.id.desc3);
loc[2] = (TextView)findViewById(R.id.loc3);
time[3] = (TextView)findViewById(R.id.time4);
desc[3] = (TextView)findViewById(R.id.desc4);
loc[3] = (TextView)findViewById(R.id.loc4);
time[4] = (TextView)findViewById(R.id.time5);
desc[4] = (TextView)findViewById(R.id.desc5);
loc[4] = (TextView)findViewById(R.id.loc5);
time[5] = (TextView)findViewById(R.id.time6);
desc[5] = (TextView)findViewById(R.id.desc6);
loc[5] = (TextView)findViewById(R.id.loc6);
time[6] = (TextView)findViewById(R.id.time7);
desc[6] = (TextView)findViewById(R.id.desc7);
loc[6] = (TextView)findViewById(R.id.loc7);
time[7] = (TextView)findViewById(R.id.time8);
desc[7] = (TextView)findViewById(R.id.desc8);
loc[7] = (TextView)findViewById(R.id.loc8);
time[8] = (TextView)findViewById(R.id.time9);
desc[8] = (TextView)findViewById(R.id.desc9);
loc[8] = (TextView)findViewById(R.id.loc9);
time[9] = (TextView)findViewById(R.id.time10);
desc[9] = (TextView)findViewById(R.id.desc10);
loc[9] = (TextView)findViewById(R.id.loc10);
}
private void fillFields(){
for(int i = 0; i < 10; i++){
time[i].setText(gi.giveTimeArray(i));
desc[i].setText(gi.giveDescriptionArray(i));
loc[i].setText(gi.giveLocationArray(i));
lat[i] = gi.giveLatitudeArray(i);
lng[i] = gi.giveLongitudeArray(i);
}
}
private void animateCamera(){
CameraPosition.builder().target(new LatLng(20, 20)).zoom(12).build();
map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
}
#Override
public void onClick(View v) {
switch(v.getId()){
case R.id.a1:
//animateCamera(lat[0],lng[0]);
break;
case R.id.a2:
//animateCamera(lat[1],lng[1]);
break;
case R.id.a3:
//animateCamera(lat[2],lng[2]);
break;
case R.id.a4:
//animateCamera(lat[3],lng[3]);
break;
case R.id.a5:
//animateCamera(lat[4],lng[4]);
break;
case R.id.a6:
//animateCamera(lat[5],lng[5]);
break;
case R.id.a7:
//animateCamera(lat[6],lng[6]);
break;
case R.id.a8:
//animateCamera(lat[7],lng[7]);
break;
case R.id.a9:
//animateCamera(lat[8],lng[8]);
break;
case R.id.a10:
//animateCamera(lat[9],lng[9]);
break;
}
}
}
Here is my manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.codexmalta.mytravelbuddy"
android:versionCode="1"
android:versionName="0.5" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="19" />
<application
android:allowBackup="true"
android:icon="#drawable/tb02"
android:label="Travel Buddy"
android:configChanges = "keyboardHidden|orientation"
>
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<activity
android:name="com.codexmalta.mytravelbuddy.MainActivity"
android:label="Travel Buddy"
android:theme="#android:style/Theme.NoTitleBar"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.codexmalta.mytravelbuddy.Itinerary"
android:label="Itinerary"
android:theme="#android:style/Theme.NoTitleBar"
android:screenOrientation="portrait">
</activity>
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="key"/>
</application>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<!-- The following two permissions are not required to use
Google Maps Android API v2, but are recommended. -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-feature
android:glEsVersion="0x00020000"
android:required="true"/>
</manifest>
And here is my fragment that holds the map in the layout xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:map="http://schemas.android.com/apk/res-auto"
android:id="#+id/RelativeLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="0dp"
android:layout_marginEnd="0dp"
android:layout_marginTop="-20dp"
android:background="#drawable/background"
android:measureAllChildren="false"
android:minHeight="75dp"
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=".Itinerary" >
<fragment
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Any help would be greatly appreciated as I just hit a wall. I searched other questions but none of them worked/ or i did not understand how they work.
I do not understand at all why you are trying to do this in a handler.
This:
GoogleMap gmap = ((SupportMapFragment).getSupportFragmentManager()
.findFragmentById(R.id.map)).getMap();
put in the onCreate() method will return the GoogleMap object.
Related
Hello I am making a bluetooth connecting android app.
I followed the instruction from developer.android.com
while I am testing my app, I look forward to it works properly, but it didn't.
I tried to get detected BLE devices names, but don't know the reason why it doesn't show me the devices name...
Arduino nano 33 IOT is adverstising bluetooth next to my android phone, and I am trying to detect it and get the Adrduino's BLE device name and address.
here is my MainActivity.java
public class MainActivity extends AppCompatActivity {
//View Contents Elements
public Button btnActivateBluetooth;
public Button btnSearchBluetooth;
public Button btnSendData;
public ListView lvSearchedDevice;
public ListView lvLog;
public TextView tvStatus;
public EditText etData;
//etc values
public ArrayAdapter<String> logAdapter;
private final int REQUEST_ENABLE_BT = 1;
private boolean mScanning = true;
//bluetooth values
public BluetoothAdapter btAdapter;
public BluetoothManager btManager;
private Handler handler;
#SuppressLint("MissingPermission")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//View Elements
btnSearchBluetooth = (Button) findViewById(R.id.btnSearchBluetooth);
btnSendData = (Button) findViewById(R.id.btnSendData);
lvSearchedDevice = (ListView) findViewById(R.id.lvSearchedDevice);
lvLog = (ListView) findViewById(R.id.log);
tvStatus = (TextView) findViewById(R.id.tvStatus);
etData = (EditText) findViewById(R.id.etData);
//etc
logAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1);
lvLog.setAdapter(logAdapter);
handler = new Handler();
// Initializes Bluetooth adapter.
btManager = (BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE);
btAdapter = btManager.getAdapter();
// displays a dialog requesting user permission to enable Bluetooth.
if (btAdapter == null || !btAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
btnSearchBluetooth.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
scanLeDevice(true);
}
});
}
//Scan devices
#SuppressLint("MissingPermission")
private void scanLeDevice(final boolean enable){
if(enable){
handler.postDelayed(new Runnable() {
#SuppressLint("MissingPermission")
#Override
public void run() {
btAdapter.stopLeScan(leScanCallback);
}
},5000);
btAdapter.startLeScan(leScanCallback);
}
else
{
btAdapter.stopLeScan(leScanCallback);
}
}
//Callback method
private BluetoothAdapter.LeScanCallback leScanCallback = new BluetoothAdapter.LeScanCallback() {
#Override
public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
runOnUiThread(new Runnable() {
#SuppressLint("MissingPermission")
#Override
public void run() {
Toast.makeText(MainActivity.this, device.getName(), Toast.LENGTH_SHORT).show();
}
});
}
};
}
and this is my Arduino nano 33 IOT's code.
#include <ArduinoBLE.h>
BLEService Toothbrush("00001101-0000-1000-8000-00805F9B34FB");
BLEStringCharacteristic ToothbrushChar("00001101-0000-1000-8000-00805F9B34FB",BLEWrite|BLERead | BLENotify, 10);
void setup() {
Serial.begin(9600);
if(!BLE.begin()){
Serial.println("Starting BLE failed.");
while(1);
}
BLE.setLocalName("HayanToothbrush");
BLE.setAdvertisedService(Toothbrush);
Toothbrush.addCharacteristic(ToothbrushChar);
BLE.addService(Toothbrush);
BLE.advertise();
Serial.println("Bluetooth device active, wating for connections...");
}
void loop() {
BLEDevice central = BLE.central();
if(central) {
Serial.print("Connected to central : ");
Serial.println(central.address());
while(central.connected()){
}
Serial.print("Disconnected from central:");
Serial.println(central.address());
}
}
I add permissions in the Mainfest as below.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.bluetooth0523">
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
<application
android:allowBackup="true"
android:dataExtractionRules="#xml/data_extraction_rules"
android:fullBackupContent="#xml/backup_rules"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.Bluetooth0523"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
But it still doesn't find me scanned device name.
I think it's on LeScanCallBack problem.
When running startLeScan, It seems not running callback method.
in addition, I am running this app on SDK_VERSION_30
and Arduino nano IOT 33 is discoverable If I use the Bluetooth function that my phone has, not my application, it will be displayed in the scan result list.
I want to get scan result on my own app.
but don't know where is the problem.
Permissions must be declared and requested depending on Android version. Main differences are:
Target Android 12 or higher
BLUETOOTH_SCAN
Target Android 11 or lower
ACCESS_FINE_LOCATION
See Bluetooth permissions for details.
There is something I don't know why I have set
android:theme="#style/AppTheme"
In AndroidManifest.xml
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme">
<activity
android:name=".MainActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".DetailActivity"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity" />
</activity>
<activity android:name=".LineChartActivity1"></activity>
<activity android:name=".RealtimeLineChartActivity">
<!--android:theme="#style/AppTheme"-->
</activity>
<activity android:label="#string/app_name"
android:theme="#style/AppTheme"
android:name=".Add_arg_activity"/>
</application>
And the RealtimeLineChartActivity's xml is
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:theme="#style/AppTheme">
<com.github.mikephil.charting.charts.LineChart
android:id="#+id/chart1"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
But!!!the screen is like this... I'm really sorry about the image, I don't have enough points in stackoverflow.
The main activity screen shot
The second activity screen shot(RealtimeLineChartActivity)
As you can see the color in the pic, the second one is white and the first one is what i want,which has applied in
#style/AppTheme
I don't why. Please, give me something useful, I have checked lots of information.
This is the second one's activity code:
public class RealtimeLineChartActivity extends DemoBase implements
OnChartValueSelectedListener {
private LineChart mChart;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_realtime_linechart);
SystemBarTintManager tintManager = new SystemBarTintManager(this);
tintManager.setStatusBarTintResource(R.color.dark_grey);
tintManager.setStatusBarTintEnabled(true);
mChart = (LineChart) findViewById(R.id.chart1);
mChart.setOnChartValueSelectedListener(this);
// no description text
mChart.setDescription("");
mChart.setNoDataTextDescription("You need to provide data for the chart.");
// enable touch gestures
mChart.setTouchEnabled(true);
// enable scaling and dragging
mChart.setDragEnabled(true);
mChart.setScaleEnabled(true);
mChart.setDrawGridBackground(false);
// if disabled, scaling can be done on x- and y-axis separately
mChart.setPinchZoom(true);
// set an alternative background color
mChart.setBackgroundColor(Color.LTGRAY);
LineData data = new LineData();
data.setValueTextColor(Color.WHITE);
// add empty data
mChart.setData(data);
Typeface tf = Typeface.createFromAsset(getAssets(), "OpenSans-Regular.ttf");
// get the legend (only possible after setting data)
Legend l = mChart.getLegend();
// modify the legend ...
// l.setPosition(LegendPosition.LEFT_OF_CHART);
l.setForm(LegendForm.LINE);
l.setTypeface(tf);
l.setTextColor(Color.WHITE);
XAxis xl = mChart.getXAxis();
xl.setTypeface(tf);
xl.setTextColor(Color.WHITE);
xl.setDrawGridLines(false);
xl.setAvoidFirstLastClipping(true);
xl.setSpaceBetweenLabels(5);
xl.setEnabled(true);
YAxis leftAxis = mChart.getAxisLeft();
leftAxis.setTypeface(tf);
leftAxis.setTextColor(Color.WHITE);
leftAxis.setAxisMaxValue(100 f);
leftAxis.setAxisMinValue(0 f);
leftAxis.setDrawGridLines(true);
YAxis rightAxis = mChart.getAxisRight();
rightAxis.setEnabled(false);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.realtime, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.actionAdd:
{
addEntry();
break;
}
case R.id.actionClear:
{
mChart.clearValues();
Toast.makeText(this, "Chart cleared!", Toast.LENGTH_SHORT).show();
break;
}
case R.id.actionFeedMultiple:
{
feedMultiple();
break;
}
}
return true;
}
private int year = 2015;
private void addEntry() {
LineData data = mChart.getData();
if (data != null) {
ILineDataSet set = data.getDataSetByIndex(0);
// set.addEntry(...); // can be called as well
if (set == null) {
set = createSet();
data.addDataSet(set);
}
// add a new x-value first
data.addXValue(mMonths[data.getXValCount() % 12] + " " + (year + data.getXValCount() / 12));
data.addEntry(new Entry((float)(Math.random() * 40) + 30 f, set.getEntryCount()), 0);
// let the chart know it's data has changed
mChart.notifyDataSetChanged();
// limit the number of visible entries
mChart.setVisibleXRangeMaximum(120);
// mChart.setVisibleYRange(30, AxisDependency.LEFT);
// move to the latest entry
mChart.moveViewToX(data.getXValCount() - 121);
// this automatically refreshes the chart (calls invalidate())
// mChart.moveViewTo(data.getXValCount()-7, 55f,
// AxisDependency.LEFT);
}
}
private LineDataSet createSet() {
LineDataSet set = new LineDataSet(null, "Dynamic Data");
set.setAxisDependency(AxisDependency.LEFT);
set.setColor(ColorTemplate.getHoloBlue());
set.setCircleColor(Color.WHITE);
set.setLineWidth(2 f);
set.setCircleRadius(4 f);
set.setFillAlpha(65);
set.setFillColor(ColorTemplate.getHoloBlue());
set.setHighLightColor(Color.rgb(244, 117, 117));
set.setValueTextColor(Color.WHITE);
set.setValueTextSize(9 f);
set.setDrawValues(false);
return set;
}
private void feedMultiple() {
new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < 500; i++) {
runOnUiThread(new Runnable() {
#Override
public void run() {
addEntry();
}
});
try {
Thread.sleep(35);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}).start();
}
#Override
public void onValueSelected(Entry e, int dataSetIndex, Highlight h) {
Log.i("Entry selected", e.toString());
}
#Override
public void onNothingSelected() {
Log.i("Nothing selected", "Nothing selected.");
}
}
Here is my styles.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppTheme" parent="AppTheme.Base">
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="colorPrimary">#3F51B5</item>
<!-- Light Indigo -->
<item name="colorPrimaryDark">#3949AB</item>
<!-- Dark Indigo -->
<item name="colorAccent">#00B0FF</item>
<!-- Blue -->
<item name="android:statusBarColor">#android:color/transparent</item>
</style>
There are two styles.xml in my project.The first is styles.xml the other one is styles-v21.xml.I did't set the item in styles-v21.xml.I use the android version is 6.0 API-23,So I copy the same item in styles.xml.It turns OK.My fault!
The First
The Second
I'm trying to parse news titles from a website using jsoup and display them in a ListView. I have been trying to solve this problem for a long time and have googled like crazy but i am unable to solve my problem or find a working solution. I have a custom class that holds two variables the news title and the link to the article. It seems as if everything parses fine but I just can't get my ListView to display correctly or at all... it continually crashes and it seams that every time I get a different error. Maybe I am making it too hard on myself. I am frustrated and can't think logically anymore... I would really appreciate any and all tips or helpful answers.
Feeds class:
public class Feeds {
private String mNewsTitle;
private String mNewsLink;
public Feeds(String newsTitle, String newsLink){
mNewsTitle = newsTitle;
mNewsLink = newsLink;
}
public String getNewsTitle(){
return mNewsTitle;
}
public void setNewsTitle(String newsTitle){
mNewsTitle = newsTitle;
}
public String getNewsLink(){
return mNewsLink;
}
public void setNewsLink(String newsLink){
mNewsTitle = newsLink;
}
}
NewsFeeds class:
public class NewsFeeds extends ListActivity {
private ArrayList<Feeds> mFeedDB = new ArrayList<Feeds>();
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_news_feeds);
HtmlParser htmlThread = new HtmlParser();
htmlThread.execute();
} // end on create
public class HtmlParser extends AsyncTask<Void, Integer, ArrayList<Feeds>> {
private static final int NETWORK_NO_ERROR = -1;
private static final int NETWORK_HOST_UNREACHABLE = 1;
private static final int NETWORK_NO_ACCESS_TO_INTERNET = 2;
private static final int NETWORK_TIME_OUT = 3;
Integer serverError = NETWORK_NO_ERROR;
ProgressDialog dialog;
protected void onPreExecute() {
// example of setting up something
dialog = new ProgressDialog(NewsFeeds.this);
dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
dialog.setMessage("Retrieving News Feeds");
dialog.show();
} // end onPreExecute
#Override
protected ArrayList<Feeds> doInBackground(Void... params) {
try {
// need http protocol
Document doc = Jsoup.connect("http://baseball-potsdam.de/news")
.get();
// get news feed titles
Elements newsFeed = doc.getElementsByClass("gdlr-blog-title");
// get all links
Elements links = newsFeed.select("a[href]");
for (Element link : links) {
// populate ArrayList with news titles and links
mFeedDB.add(new Feeds(link.text(), link.attr("href")));
}
return mFeedDB;
// } catch (IOException e) {
// e.printStackTrace();
} catch (ConnectException e) {
serverError = NETWORK_NO_ACCESS_TO_INTERNET;
return null;
} catch (UnknownHostException e) {
serverError = NETWORK_HOST_UNREACHABLE;
return null;
} catch (SocketTimeoutException e) {
serverError = NETWORK_TIME_OUT;
return null;
} catch (IOException e) {
e.printStackTrace();
} // end try catch
return null;
} // end doInBackground
protected void onProgressUpdate(Integer... progress) {
} // end onProgressUpdate
protected void onPostExecute(ArrayList<Feeds> result) {
if (result != null) {
ListView listview = (ListView) findViewById(R.id.list_view_news_feeds);
listview.setAdapter(new ArrayAdapter<Feeds>(NewsFeeds.this, android.R.layout.simple_list_item_1 , mFeedDB));
if (dialog.isShowing()) {
dialog.dismiss();
} // end if
} else {
switch (serverError) {
case NETWORK_NO_ERROR:
Toast.makeText(NewsFeeds.this,
"Probably, invalid response from server",
Toast.LENGTH_LONG).show();
break;
case NETWORK_NO_ACCESS_TO_INTERNET:
// You can customize error message (or behavior) for
// different type of error
case NETWORK_TIME_OUT:
case NETWORK_HOST_UNREACHABLE:
Toast.makeText(NewsFeeds.this, "Error in Connection",
Toast.LENGTH_LONG).show();
break;
}
} // end if else
} // end onPostExecute
} // end HtmlParser class
} // end NewsFeeds
activity_news_feeds.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ListView
android:id="#+id/list_view_news_feeds"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:dividerHeight="0.1dp"
android:divider="#0000CC"
/>
</LinearLayout>
NewsManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.kylehopeman.android.porcupinesnews"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="21" />
<uses-permission android:name="android.permission.INTERNET" />"
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.kylehopeman.android.porcupinesnews.MainMenu"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.kylehopeman.android.porcupinesnews.NewsFeeds"
android:label="#string/app_name" >
<intent-filter>
<action android:name="com.kylehopeman.android.porcupinesnews.NewsFeeds" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
</manifest>
If you are getting an error with the ListView it looks like it only gets instantiated in the postExecute block. Is it possible to instantiate it in the onCreate() and have it declared where you declare mFeedDB?
After changing the first line in my NewsFeeds.java file from:
public class NewsFeeds extends ListActivity
to:
public class NewsFeeds extends Activity
the errors went away, the app compiled and worked just like I wanted it to.
I want to have MapView inside my Fragment
This is my FragmentLayout xml file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#17df0d"
android:orientation="vertical" >
<com.google.android.gms.maps.MapView
android:id="#+id/mapview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/textView1"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_marginBottom="70dp" >
</com.google.android.gms.maps.MapView>
</RelativeLayout>
My AndroidManifest.xml file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="a.b.c.d"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="11"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="your_api_key" />
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
</application>
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<permission
android:name="a.b.c.d.permission.MAPS_RECEIVE"
android:protectionLevel="signature" />
<uses-permission android:name="a.b.c.d.permission.MAPS_RECEIVE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
</manifest>
and my Fragment class
public class ReportFragment extends Fragment implements LocationListener {
MapView mapView = null; //eventually it is being read from view and assigned
when I launch the app, I do not see any map view in my Fragment
From Josh Holtz's example on GitHub:
You should add MapView in your Layout like
<com.google.android.gms.maps.MapView
android:id="#+id/mapview"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
and implement your Fragment like
public class SomeFragment extends Fragment {
MapView mapView;
GoogleMap map;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.some_layout, container, false);
// Gets the MapView from the XML layout and creates it
mapView = (MapView) v.findViewById(R.id.mapview);
mapView.onCreate(savedInstanceState);
// Gets to GoogleMap from the MapView and does initialization stuff
map = mapView.getMap();
map.getUiSettings().setMyLocationButtonEnabled(false);
map.setMyLocationEnabled(true);
// Needs to call MapsInitializer before doing any CameraUpdateFactory calls
try {
MapsInitializer.initialize(this.getActivity());
} catch (GooglePlayServicesNotAvailableException e) {
e.printStackTrace();
}
// Updates the location and zoom of the MapView
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(new LatLng(43.1, -87.9), 10);
map.animateCamera(cameraUpdate);
return v;
}
#Override
public void onResume() {
mapView.onResume();
super.onResume();
}
#Override
public void onDestroy() {
super.onDestroy();
mapView.onDestroy();
}
#Override
public void onLowMemory() {
super.onLowMemory();
mapView.onLowMemory();
}
}
Adding to M D's answer:
From documentation:
A GoogleMap must be acquired using getMapAsync(OnMapReadyCallback). The MapView automatically initializes the maps system and the view.
According to this, the more correct way to initialize GoogleMap is using getMapAsync.
Note that your class has to implement OnMapReadyCallback
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_map_page, container, false);
mMapView = (MapView) v.findViewById(R.id.map_view);
mMapView.onCreate(savedInstanceState);
mMapView.getMapAsync(this); //this is important
return v;
}
#Override
public void onMapReady(GoogleMap googleMap) {
mGoogleMap = googleMap;
mGoogleMap.getUiSettings().setZoomControlsEnabled(true);
mGoogleMap.addMarker(new MarkerOptions().position(/*some location*/));
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(/*some location*/, 10));
}
#Override
public void onResume() {
super.onResume();
mMapView.onResume();
}
#Override
public void onPause() {
super.onPause();
mMapView.onPause();
}
#Override
public void onDestroy() {
super.onDestroy();
mMapView.onDestroy();
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mMapView.onSaveInstanceState(outState);
}
#Override
public void onLowMemory() {
super.onLowMemory();
mMapView.onLowMemory();
}
In case somebody is looking for a Kotlin version of MapView Fragment ;)
class MapViewKotlinFragment : Fragment(), OnMapReadyCallback {
private var mMap: MapView? = null
override fun onSaveInstanceState(outState: Bundle?) {
super.onSaveInstanceState(outState)
mMap?.onSaveInstanceState(outState)
}
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater?.inflate(R.layout.fragment_map, container, false)
mMap = view?.findViewById(R.id.mapViewPlaces) as MapView
mMap?.onCreate(savedInstanceState)
mMap?.getMapAsync(this)
return view
}
override fun onResume() {
super.onResume()
mMap?.onResume()
}
override fun onPause() {
super.onPause()
mMap?.onPause()
}
override fun onStart() {
super.onStart()
mMap?.onStart()
}
override fun onStop() {
super.onStop()
mMap?.onStop()
}
override fun onDestroy() {
super.onDestroy()
mMap?.onDestroy()
}
override fun onLowMemory() {
super.onLowMemory()
mMap?.onLowMemory()
}
override fun onMapReady(googleMap: GoogleMap) {
googleMap.addMarker(MarkerOptions().position(LatLng(0.0, 0.0)).title("Marker"))
}
Old post, but might help someone who is looking to implement maps inside the fragment. Below is the detailed example using kotlin:
First, add the permission in AndroidManifest.xml file:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
Then under the application tag add meta-data in AndroidManifest.xml file:
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="#string/map_api_key"/>
<uses-library
android:name="org.apache.http.legacy"
android:required="false" />
*To get api link visit: https://developers.google.com/maps/documentation/android-sdk/get-api-key
Implement play services in build.gradle file:
implementation "com.google.android.gms:play-services-location:15.0.1"
implementation "com.google.android.gms:play-services-places:15.0.1"
implementation 'com.google.android.libraries.places:places:2.3.0'
Add pulgin: apply plugin: 'com.google.gms.google-services'
Add maps fragment inside your fragment.xml file:
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
In your fragment.kt file, implement OnMapReadyCallback. Initialize the google map using getMapAsync(). Below code will let you integrate the google map and point it to your current location.
package "Your_Package_Name"
import android.Manifest
import android.content.ContentValues.TAG
import android.content.DialogInterface
import android.content.pm.PackageManager
import android.location.Location
import android.os.Bundle
import androidx.core.app.ActivityCompat
import androidx.fragment.app.Fragment
import androidx.core.content.ContextCompat
import androidx.appcompat.app.AlertDialog
import android.util.Log
import android.view.LayoutInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.TextView
import android.widget.Toast
import com.example.utilitybox.R
import com.google.android.gms.location.FusedLocationProviderClient
import com.google.android.gms.maps.*
import com.google.android.gms.maps.model.CameraPosition
import com.google.android.gms.maps.model.LatLng
import com.google.android.gms.maps.model.Marker
import com.google.android.gms.maps.model.MarkerOptions
import com.google.android.libraries.places.api.model.Place
import com.google.android.libraries.places.api.net.FindCurrentPlaceRequest
import com.google.android.libraries.places.api.net.PlacesClient
class FragmentHome : Fragment(), OnMapReadyCallback {
private var v:View?=null
private var locationPermissionGranted = false
private var googleMap: GoogleMap?=null
private var fusedLocationProviderClient: FusedLocationProviderClient?=null
private val defaultLocation = LatLng(-33.8523341, 151.2106085)
private var cameraPosition: CameraPosition? = null
private var placesClient: PlacesClient?=null
private var lastKnownLocation: Location? = null
private var likelyPlaceNames: Array<String?> = arrayOfNulls(0)
private var likelyPlaceAddresses: Array<String?> = arrayOfNulls(0)
private var likelyPlaceAttributions: Array<List<*>?> = arrayOfNulls(0)
private var likelyPlaceLatLngs: Array<LatLng?> = arrayOfNulls(0)
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
if (savedInstanceState != null) {
lastKnownLocation = savedInstanceState.getParcelable(KEY_LOCATION)
cameraPosition = savedInstanceState.getParcelable(KEY_CAMERA_POSITION)
}
v = inflater.inflate(R.layout.fragment_fragment_home, container, false)
if(getString(R.string.map_api_key).isEmpty()){
Toast.makeText(activity, "Add your own API key in MapWithMarker/app/secure.properties as MAPS_API_KEY=YOUR_API_KEY", Toast.LENGTH_LONG).show()
}
val mapFragment = childFragmentManager.findFragmentById(R.id.map) as? SupportMapFragment
mapFragment?.getMapAsync(this)
getLocationPermission()
return v
}
override fun onSaveInstanceState(outState: Bundle) {
googleMap?.let { map ->
outState.putParcelable(KEY_CAMERA_POSITION, map.cameraPosition)
outState.putParcelable(KEY_LOCATION, lastKnownLocation)
}
super.onSaveInstanceState(outState)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == R.id.option_get_place) {
showCurrentPlace()
}
return true
}
override fun onMapReady(googleMap: GoogleMap) {
this.googleMap = googleMap
this.googleMap?.setInfoWindowAdapter(object : GoogleMap.InfoWindowAdapter {
override fun getInfoWindow(arg0: Marker): View? {
return null
}
override fun getInfoContents(marker: Marker): View {
val infoWindow = layoutInflater.inflate(R.layout.custom_info_contents,
v?.findViewById(R.id.map), false)
val title = infoWindow.findViewById<TextView>(R.id.title)
title.text = marker.title
val snippet = infoWindow.findViewById<TextView>(R.id.snippet)
snippet.text = marker.snippet
return infoWindow
}
})
getLocationPermission()
updateLocationUI()
getDeviceLocation()
}
private fun getLocationPermission() {
if (ContextCompat.checkSelfPermission(this.requireContext(),
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
locationPermissionGranted = true
} else {
ActivityCompat.requestPermissions(requireActivity(), arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION)
}
}
override fun onRequestPermissionsResult(requestCode: Int,
permissions: Array<String>,
grantResults: IntArray) {
locationPermissionGranted = false
when (requestCode) {
PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION -> {
if (grantResults.isNotEmpty() &&
grantResults[0] == PackageManager.PERMISSION_GRANTED) {
locationPermissionGranted = true
}
}
}
updateLocationUI()
}
private fun showCurrentPlace() {
if (googleMap == null) {
return
}
if (locationPermissionGranted) {
val placeFields = listOf(Place.Field.NAME, Place.Field.ADDRESS, Place.Field.LAT_LNG)
val request = FindCurrentPlaceRequest.newInstance(placeFields)
val placeResult = placesClient?.findCurrentPlace(request)
placeResult?.addOnCompleteListener { task ->
if (task.isSuccessful && task.result != null) {
val likelyPlaces = task.result
val count = if (likelyPlaces != null && likelyPlaces.placeLikelihoods.size < M_MAX_ENTRIES) {
likelyPlaces.placeLikelihoods.size
} else {
M_MAX_ENTRIES
}
var i = 0
likelyPlaceNames = arrayOfNulls(count)
likelyPlaceAddresses = arrayOfNulls(count)
likelyPlaceAttributions = arrayOfNulls<List<*>?>(count)
likelyPlaceLatLngs = arrayOfNulls(count)
for (placeLikelihood in likelyPlaces?.placeLikelihoods ?: emptyList()) {
likelyPlaceNames[i] = placeLikelihood.place.name
likelyPlaceAddresses[i] = placeLikelihood.place.address
likelyPlaceAttributions[i] = placeLikelihood.place.attributions
likelyPlaceLatLngs[i] = placeLikelihood.place.latLng
i++
if (i > count - 1) {
break
}
}
openPlacesDialog()
} else {
Log.e(TAG, "Exception: %s", task.exception)
}
}
} else {
Log.i(TAG, "The user did not grant location permission.")
googleMap?.addMarker(MarkerOptions()
.title(getString(R.string.default_info_title))
.position(defaultLocation)
.snippet(getString(R.string.default_info_snippet)))
getLocationPermission()
}
}
private fun updateLocationUI() {
if (googleMap == null) {
return
}
try {
if (locationPermissionGranted) {
googleMap?.isMyLocationEnabled = true
googleMap?.uiSettings?.isMyLocationButtonEnabled = true
} else {
googleMap?.isMyLocationEnabled = false
googleMap?.uiSettings?.isMyLocationButtonEnabled = false
lastKnownLocation = null
getLocationPermission()
}
} catch (e: SecurityException) {
Log.e("Exception: %s", e.message, e)
}
}
private fun getDeviceLocation() {
try {
if (locationPermissionGranted) {
val locationResult = fusedLocationProviderClient?.lastLocation
if (locationResult != null) {
locationResult.addOnCompleteListener(this.requireActivity()) { task ->
if (task.isSuccessful) {
// Set the map's camera position to the current location of the device.
lastKnownLocation = task.result
if (lastKnownLocation != null) {
googleMap?.moveCamera(CameraUpdateFactory.newLatLngZoom(
LatLng(lastKnownLocation!!.latitude,
lastKnownLocation!!.longitude), DEFAULT_ZOOM.toFloat()))
}
} else {
Log.d(TAG, "Current location is null. Using defaults.")
Log.e(TAG, "Exception: %s", task.exception)
googleMap?.moveCamera(CameraUpdateFactory
.newLatLngZoom(defaultLocation, DEFAULT_ZOOM.toFloat()))
googleMap?.uiSettings?.isMyLocationButtonEnabled = false
}
}
}
}
} catch (e: SecurityException) {
Log.e("Exception: %s", e.message, e)
}
}
private fun openPlacesDialog() {
val listener = DialogInterface.OnClickListener { dialog, which ->
val markerLatLng = likelyPlaceLatLngs[which]
var markerSnippet = likelyPlaceAddresses[which]
if (likelyPlaceAttributions[which] != null) {
markerSnippet = """
$markerSnippet
${likelyPlaceAttributions[which]}
""".trimIndent()
}
googleMap?.addMarker(MarkerOptions()
.title(likelyPlaceNames[which])
.position(markerLatLng!!)
.snippet(markerSnippet))
googleMap?.moveCamera(CameraUpdateFactory.newLatLngZoom(markerLatLng,
DEFAULT_ZOOM.toFloat()))
}
AlertDialog.Builder(this.requireContext())
.setTitle(R.string.pick_place)
.setItems(likelyPlaceNames, listener)
.show()
}
companion object {
private const val DEFAULT_ZOOM = 15
private const val PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1
private const val KEY_CAMERA_POSITION = "camera_position"
private const val KEY_LOCATION = "location"
private const val M_MAX_ENTRIES = 5
}
}
Once done add custom_info_contents.xml file in layout folder:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layoutDirection="locale"
android:orientation="vertical">
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:textColor="#ff000000"
android:textStyle="bold" />
<TextView
android:id="#+id/snippet"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#ff7f7f7f" />
</LinearLayout>
Add below code in strings.xml file:
<string name="map_api_key">YOUR_API_KEY</string>
<!--Map strings-->
<string name="title_activity_maps">Current Place Details</string>
<string name="default_info_title">Default Location</string>
<string name="default_info_snippet">No places found, because location permission is disabled.</string>
<string name="option_get_place">Get place</string>
<string name="pick_place">Choose a place</string>
In menu folder create current_place_menu.xml file and add below code:
<?xml version="1.0" encoding="utf-8"?><!--
Copyright (C) 2016 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/option_get_place"
android:title="#string/option_get_place"
app:showAsAction="always"/>
</menu>
Hope this helps...
Makes sure you are overriding or calling OnDestroyView as well as OnDestroy. Something like ...
public override void OnDestroy()
{
base.OnDestroy();
MapView.OnDestroy();
OnDestroyView();
}
public override void OnDestroyView()
{
base.OnDestroyView();
mapReadyCallbackList.Clear();
}
I'm trying to get textview to display a number, but it will not.
My activity code:
package com.example.gotteron;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class Classement extends Activity{
TextView textview;
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.classement);
GetCode getCode = new GetCode();
textview = (TextView)findViewById(R.id.textView1);
try {
textview.setText(getCode.test());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Class to get HTMl:
//Package
package com.example.gotteron;
//Import
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
public class GetCode{
public String test() throws Exception{
//Recupérer le code HTML de la page
URL oracle = new URL("http://www.nationalleague.ch/NL/fr/");
URLConnection yc = oracle.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(
yc.getInputStream()));
String inputLine;
String s1 = "";
while ((inputLine = in.readLine()) != null)
s1 = s1 + inputLine;
in.close();
int Berne = s1.indexOf(">SC Bern</td>");
String s3 = String.valueOf(Berne);
return s3;
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
XML file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#drawable/background">
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/firstPosition" />
</LinearLayout>
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.gotteron"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.gotteron.Principal"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="Classement" android:label="#string/app_name"></activity>
<activity android:name="Calendrier" android:label="#string/app_name"></activity>
<activity android:name="Live" android:label="#string/app_name"></activity>
</application>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
</manifest>
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
EDIT:
Thanks for the code but there's still a problem. When I run the Application the textview displays his default message. During this time, the logcat displays a lot of messages:
http://pastebin.com/244grjYt
and at the end the app crashes
Essentially, this is what the other answers are about. Since you haven't check anything as answer, maybe this will help.
public class MyClass extends Activity {
TextView textview;
public void onCreate(Bundle bundle) {
super.onCreate(savedInstanceState);
setContentView(R.layout.classement);
textview = (TextView)findViewById(R.id.textview);
new NetworkOperation().execute();
}
private class NetworkOperation extends AsyncTask<Void, Void, String> {
protected String doInBackground(Void... params) {
try {
URL oracle = new URL("http://www.nationalleague.ch/NL/fr/");
URLConnection yc = oracle.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream()));
String inputLine;
String s1 = "";
while ((inputLine = in.readLine()) != null)
s1 = s1 + inputLine;
in.close();
int Berne = s1.indexOf(">SC Bern</td>");
String s3 = String.valueOf(Berne);
return s3;
}
catch (IOException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String result) {
textview.setText(result);
}
}
}
You cannot make a network connection (HTTP connection) i the ui thread, try to move the call to getCode.test() into another thread or better into an AsyncTask..
You are facing NetworkOnMainThread Exception which is quite common on Emulators that are running on API level 11 and more when you are writing Network Related code in UI Thread. You change your code into doInBackground() of an AsyncTask and run it.
In your case as you are throwing Exception in test() it will not crash your app because Exceptions are caught by Exception.
Example Code:
class FetchResultTask extends AsyncTask<Void,Void,String>
{
protected String doInBackground()
{
//your network related code.
}
protected void onPostExecute(String result)
{
super.onPostExecute(result);
//set the result to TextView here.
}
}