I am getting this exception when trying to start a new activity through a method in my Main
java.lang.NullPointerException: Attempt to invoke virtual method
'android.content.Context android.content.Context.getApplicationContext()
' on a null object reference
The method i am using to start the new activity is not called in the main activity. I think this is what is causing the issue, since i tried to call the method in the OnCreate method of the main activity, and it worked.
However i cannot figure out a way to fix this, a friend suggested that i used singleton, but that didn't work - or maybe my understanding of how to use it is just too limited.
This is my main class:
package gruppe16.sdupay;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Handler;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import java.util.ArrayList;
/**
* An example full-screen activity that shows and hides the system UI (i.e.
* status bar and navigation/system bar) with user interaction.
*/
public class Main extends Activity {
static EditText et1, et2, et3, et4;
private String password = "1234";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et1 = (EditText) findViewById(R.id.editText1);
et2 = (EditText) findViewById(R.id.editText2);
et3 = (EditText) findViewById(R.id.editText3);
et4 = (EditText) findViewById(R.id.editText4);
et1.addTextChangedListener(new CustomTextWatcher(et1));
et2.addTextChangedListener(new CustomTextWatcher(et2));
et3.addTextChangedListener(new CustomTextWatcher(et3));
et4.addTextChangedListener(new CustomTextWatcher(et4));
}
public void login (String passInput){
if(passInput.equals(password)){
Log.d("asd", "PASS IS CORRECT");
Intent appIntent = new Intent(getApplicationContext(), AppActivity.class);
startActivity(appIntent);
} else {
Log.d("asd2", "PASS IS NOT CORRECT");
}
}
}
This is my CustomTextWatcher class
package gruppe16.sdupay;
import android.content.Intent;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.widget.EditText;
/**
* Created by jonaspedersen on 15/12/15.
*/
public class CustomTextWatcher implements TextWatcher {
static String et1String, et2String, et3String, et4String;
private EditText mEditText;
private Main MainObject = new Main();
private String passString;
public CustomTextWatcher(EditText e) {
mEditText = e;
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
if (mEditText == Main.et1){
et1String = Main.et1.getText().toString();
Main.et2.requestFocus();
} else if (mEditText == Main.et2){
et2String = Main.et2.getText().toString();
Main.et3.requestFocus();
} else if (mEditText == Main.et3){
et3String = Main.et3.getText().toString();
Main.et4.requestFocus();
} else if (mEditText == Main.et4){
et4String = Main.et4.getText().toString();
passString = et1String + et2String + et3String + et4String;
MainObject.login(passString);
}
}
}
AndroidManifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="gruppe16.sdupay">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#android:style/Theme.Light.NoTitleBar">
<activity
android:name=".Main"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="#string/app_name"
android:theme="#style/SDUTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".AppActivity"
android:label="#string/title_activity_app"></activity>
</application>
</manifest>
use
Intent appIntent = new Intent(Main.this, AppActivity.class);
also change CustomTextWatcher constructor
private Main MainObject;
private String passString;
public CustomTextWatcher(EditText e,Main MainObject) {
mEditText = e;
this.MainObject = MainObject;
}
and set TextWatcher like
et1.addTextChangedListener(new CustomTextWatcher(et1),Main.this);
Related
I've been playing around with some Android recently and have the following setup:
I have app A, which is a service. This has no activity. Here's its manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.sandbox.sampleservice">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.SampleService">
<service
android:name=".DummyService"
android:exported="true"
android:enabled="true">
</service>
</application>
</manifest>
and here's the Java code:
package com.sandbox.sampleservice;
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.util.Log;
public class DummyService extends Service {
private static final String TAG = "DummyService";
static class MessageHandler extends Handler {
#Override
public void handleMessage(Message msg) {
// TODO: sort this later
super.handleMessage(msg);
}
}
Messenger mMessenger = null;
#Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "Binding");
mMessenger = new Messenger(new MessageHandler());
return mMessenger.getBinder();
}
#Override
public boolean onUnbind(Intent intent) {
Log.i(TAG, "No longer bound");
return false;
}
}
I then have an app B with an empty activity which I want to bind to the service in app A. This is it's MainActivity:
package com.sandbox.sampleclient;
import androidx.appcompat.app.AppCompatActivity;
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.util.Log;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "SampleClient";
private ServiceConnection mServiceConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i(TAG, "Bound");
}
#Override
public void onServiceDisconnected(ComponentName name) {
Log.i(TAG, "Unbound");
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.sandbox.sampleservice", ".DummyService"));
boolean result = this.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
if (result) {
Toast.makeText(this, "success", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "failed", Toast.LENGTH_SHORT).show();
}
}
}
I'm running on the default emulator that comes with Android Studio - API 30/x86.
I've installed the service using the installDebug Gradle task and can see the app in the Settings. But running app B, the call to bindService() returns false (it shows the failure toast). And I have the following message in logcat:
2021-04-03 20:33:59.743 500-1764/system_process W/ActivityManager: Unable to start service Intent { cmp=com.sandbox.sampleservice/.DummyService } U=0: not found
I've tried a few things - using the app context rather than the activity one when binding, using the fully qualified class name, and more. No change in behaviour, and the error in logcat is always the same.
I would like to provide a service that can be called by other app. Therefore, I have a service and an aidl. But when I try to have a separate application to bind this service (bindService), it just returns me false which means fail. Here is my code.
I'm using the code from books Pro Android 2
I've already tried many solutions in other questions similar to this, but there isn't any working solution for me.
I've tried fix the aidl intent filter but it's still not working
I've tried fix the package name and class name in client app, but it's still not working.
Please help me!
On Client :
// IStockQuoteService.aidl
package id.ac.ui.cs.mobileprogramming.ahmad_fauzan_amirul_isnain.stockquoteservice;
// Declare any non-default types here with import statements
interface IStockQuoteService {
double getQuote(String ticker);
}
package id.ac.ui.cs.mobileprogramming.ahmad_fauzan_amirul_isnain.stockquoteclient;
import id.ac.ui.cs.mobileprogramming.ahmad_fauzan_amirul_isnain.stockquoteservice.IStockQuoteService;
import android.app.Activity;
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.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends Activity {
protected static final String TAG = "StockQuoteClient";
private IStockQuoteService stockService = null;
private Button bindBtn;
private Button callBtn;
private Button unbindBtn;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bindBtn = (Button)findViewById(R.id.bindBtn);
bindBtn.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View view) {
Intent intent = new Intent();
intent.setClassName("com.id.ac.ui.cs.mobileprogramming" +
".ahmad_fauzan_amirul_isnain.stockquoteservice",
"com.id.ac.ui.cs.mobileprogramming.ahmad_fauzan_amirul_isnain" +
".stockquoteservice.IStockQuoteService");
Log.d("Hasil", String.valueOf(bindService(intent,
serConn, Context.BIND_AUTO_CREATE)));
bindBtn.setEnabled(false);
callBtn.setEnabled(true);
unbindBtn.setEnabled(true);
}});
callBtn = (Button)findViewById(R.id.callBtn);
callBtn.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View view) {
callService();
}});
callBtn.setEnabled(false);
unbindBtn = (Button)findViewById(R.id.unbindBtn);
unbindBtn.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View view) {
unbindService(serConn);
bindBtn.setEnabled(true);
callBtn.setEnabled(false);
unbindBtn.setEnabled(false);
}});
unbindBtn.setEnabled(false);
}
private void callService() {
try {
double val = stockService.getQuote("SYH");
Toast.makeText(MainActivity.this, "Value from service is "+val,
Toast.LENGTH_SHORT).show();
} catch (RemoteException ee) {
Log.e("MainActivity", ee.getMessage(), ee);
}
}
private ServiceConnection serConn = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder service)
{
Log.v(TAG, "onServiceConnected() called");
stockService = IStockQuoteService.Stub.asInterface(service);
callService();
}
#Override
public void onServiceDisconnected(ComponentName name) {
Log.v(TAG, "onServiceDisconnected() called");
stockService = null;
}
};
}
On Service :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="id.ac.ui.cs.mobileprogramming.ahmad_fauzan_amirul_isnain.stockquoteservice">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name="StockQuoteService">
<intent-filter>
<action android:name="com.id.ac.ui.cs.mobileprogramming.ahmad_fauzan_amirul_isnain.stockquoteservice.IStockQuoteService"
/>
</intent-filter>
</service>
</application>
</manifest>
package id.ac.ui.cs.mobileprogramming.ahmad_fauzan_amirul_isnain.stockquoteservice;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
public class StockQuoteService extends Service
{
private static final String TAG = "StockQuoteService";
public class StockQuoteServiceImpl extends IStockQuoteService.Stub
{
#Override
public double getQuote(String ticker) throws RemoteException
{
Log.v(TAG, "getQuote() called for " + ticker);
return 20.0;
}
}
#Override
public void onCreate() {
super.onCreate();
Log.v(TAG, "onCreate() called");
}
#Override
public void onDestroy()
{
super.onDestroy();
Log.v(TAG, "onDestroy() called");
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Log.v(TAG, "onStart() called");
}
#Override
public IBinder onBind(Intent intent)
{
Log.v(TAG, "onBind() called");
return new StockQuoteServiceImpl();
}
}
// IStockQuoteService.aidl
package id.ac.ui.cs.mobileprogramming.ahmad_fauzan_amirul_isnain.stockquoteservice;
// Declare any non-default types here with import statements
interface IStockQuoteService {
double getQuote(String ticker);
}
I'm using the code from books Pro Android 2
That book is from 2010. Much of that book will be out of date. Please use something newer. If nothing else, you can download older editions of one of my books for free. Right now, the most recent version of those is from 2015 — while that too is a bit old, it is much more up to date than a book from 2010.
I've already tried many solutions in other questions similar to this, but there isn't any working solution for me.
You have:
intent.setClassName("com.id.ac.ui.cs.mobileprogramming" +
".ahmad_fauzan_amirul_isnain.stockquoteservice",
"com.id.ac.ui.cs.mobileprogramming.ahmad_fauzan_amirul_isnain" +
".stockquoteservice.IStockQuoteService");
The package in your manifest has id.ac.ui.cs.mobileprogramming.ahmad_fauzan_amirul_isnain.stockquoteservice. Assuming that your applicationId in your module's build.gradle file is the same, I think that this matches what you have in your code. Your application ID is very long — in the future, I recommend that you use something shorter and easier to visually compare.
However, your class name is wrong. Your <service> class is StockQuoteService, not IStockQuoteService. IStockQuoteService is the name of the AIDL, not the service, and your Intent needs to point to the service. So, try:
intent.setClassName("com.id.ac.ui.cs.mobileprogramming" +
".ahmad_fauzan_amirul_isnain.stockquoteservice",
"com.id.ac.ui.cs.mobileprogramming.ahmad_fauzan_amirul_isnain" +
".stockquoteservice.StockQuoteService");
Or, to reduce duplication:
String packageName = "com.id.ac.ui.cs.mobileprogramming" +
".ahmad_fauzan_amirul_isnain.stockquoteservice";
intent.setClassName(packageName, packageName+".StockQuoteService");
I have written a code to list nearby Bluetooth Devices but my code is unable to detect any.
According to my code, the action just starts and end and not print any device in logs when I do String action = intent.getAction(); Log.i("Action",action);
in onRecieve() under BroadCastReciever.
Here is my MainActivity.java :
package com.example.findbluetoothdemo;
import androidx.appcompat.app.AppCompatActivity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
TextView statusTextView;
ListView listView;
Button searchButton;
ArrayList<String> bluetoothDevices = new ArrayList<>();
ArrayList<String> addresses = new ArrayList<>();
ArrayAdapter arrayAdapter;
BluetoothAdapter bluetoothAdapter;
private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.i("Action",action);
if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
statusTextView.setText("Finished");
searchButton.setEnabled(true);
} else if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
String name = device.getName();
String address = device.getAddress();
String rssi = Integer.toString(intent.getShortExtra(BluetoothDevice.EXTRA_RSSI,Short.MIN_VALUE));
Log.i("Device Found","Nmae :"+name+" Address :"+address+" RSSI :"+rssi);
if (!addresses.contains(address)) {
addresses.add(address);
String deviceString = "";
if (name==null || name.equals("")) {
deviceString = address+" - RSSI "+rssi+"dBm";
} else {
deviceString = name+" - RSSI "+rssi+"dBm";
}
bluetoothDevices.add(deviceString);
arrayAdapter.notifyDataSetChanged();
}
}
}
};
public void searchFunction(View view) {
bluetoothDevices.add("ADDING NEW DEVICES...");
statusTextView.setText("Searching...");
searchButton.setEnabled(false);
arrayAdapter.notifyDataSetChanged();
bluetoothDevices.clear();
addresses.clear();
bluetoothAdapter.startDiscovery();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
statusTextView = findViewById(R.id.statusTextView);
listView = findViewById(R.id.listView);
searchButton = findViewById(R.id.button);
arrayAdapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1,bluetoothDevices);
listView.setAdapter(arrayAdapter);
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(broadcastReceiver ,intentFilter);
}
}
And here is AndroidManifest.xml :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.findbluetoothdemo">
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"></uses-permission>
<uses-permission android:name="android.permission.BLUETOOTH"></uses-permission>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
You need to ask for permission if you haven't done already.
int premissionCehck = context.checkSelfPermission("Manifest.premission.ACCES_FINE_LOCATION");
premissionCehck += context.checkSelfPermission("Manifest.premission.ACCES_FINE_LOCATION");
if (premissionCehck != 0) {
ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, 1001);
}
Take Care, If you already denied permission once, the permission request doesn't appear again, so you need to give it free in your android settings.
I understand this questions has been asked many times, for each question that has already been asked, the implementation is different from mine. The method I used create and call the intentService for a geocoder, was used from the android dev tutorial site.
https://developer.android.com/training/location/display-address.html.
I have gone over the the tutorial 3 times over to make sure I wasn't missing anything, but it is clear that I am.
Here is my manifest file, I have added the location and internet permissions.
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".selectRouteAndTransportMethod">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<service
android:name=".FetchAddressIntentService"
android:exported="false"/>
</activity>
<!--
The API key for Google Maps-based APIs is defined as a string resource.
(See the file "res/values/google_maps_api.xml").
Note that the API key is linked to the encryption key used to sign the APK.
You need a different API key for each encryption key, including the release key that is used to
sign the APK for publishing.
You can define the keys for the debug and release targets in src/debug/ and src/release/.
-->
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="#string/google_maps_key" />
<activity
android:name="user.com.commuterapp.MapsActivity"
android:label="#string/title_activity_maps"></activity><!-- ATTENTION: This was auto-generated to add Google Play services to your project for
App Indexing. See https://g.co/AppIndexing/AndroidStudio for more information. -->
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
</application>
Here is my main activity: All I am doing here is using a buttonClick to create the intent and to start the intent.
package user.com.commuterapp;
import android.app.PendingIntent;
import android.content.Intent;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationServices;
import user.com.commuterapp.R;
import static java.lang.Boolean.TRUE;
public class selectRouteAndTransportMethod extends AppCompatActivity {
Intent mIntent;
PendingIntent mPendingIntent;
myLocation mCurrentLocation;
private AddressResultReceiver mResultReceiver;
public static final String TAG = selectRouteAndTransportMethod.class.getSimpleName();
/**
* ATTENTION: This was auto-generated to implement the App Indexing API.
* See https://g.co/AppIndexing/AndroidStudio for more information.
*/
private GoogleApiClient client;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_select_route_and_transport_method);
mIntent = new Intent(this, selectRouteAndTransportMethod.class);
mPendingIntent = PendingIntent.getActivity(this, 0, mIntent, 0);
mCurrentLocation = new myLocation(this, this, mPendingIntent);
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
}
#Override
protected void onStart() {
super.onStart();
Log.d(TAG, "On Start");
mCurrentLocation.connect();
boolean connecting = mCurrentLocation.mGoogleApiClient.isConnecting();
boolean registered = mCurrentLocation.mGoogleApiClient.isConnectionCallbacksRegistered(mCurrentLocation);
//ConnectionResult connectionResult = mCurrentLocation.mGoogleApiClient.getConnectionResult(LocationServices.API);
if (connecting == TRUE) {
Log.d(TAG, "Connecting");
}
if (registered == TRUE) {
Log.d(TAG, "registered");
}
}
#Override
protected void onResume() {
super.onResume();
mCurrentLocation.connect();
}
#Override
protected void onPause() {
super.onPause();
// mCurrentLocation.disconnect();
}
protected void buttonOriginClick(View view)
{
Log.d(TAG,"retrieving address");
retrieveAddress();
}
protected void retrieveAddress() {
Intent geoCoderIntent = new Intent(this, FetchAddressIntentService.class);
geoCoderIntent.putExtra(FetchAddressIntentService.Constants.RECIEVER, mResultReceiver);
geoCoderIntent.putExtra(FetchAddressIntentService.Constants.LOCATION_DATA_EXTRA, mCurrentLocation.mCurrentLocation);
startService(geoCoderIntent);
}
}
And lastly here is the intentService class. This was straight out of the android dev tutorial site, nothing original here.
package user.com.commuterapp;
import android.app.IntentService;
import android.content.Intent;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.os.Bundle;
import android.support.v4.os.ResultReceiver;
import android.text.TextUtils;
import android.util.Log;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import static android.content.ContentValues.TAG;
/**
* Created by User on 1/21/2017.
*/
public class FetchAddressIntentService extends IntentService {
public final class Constants{
public static final int SUCCESS_RESULT = 0;
public static final int FAILURE_RESULT = 1;
public static final String PACKAGE_NAME =
"user.com.commuterapp";
public static final String RECIEVER = PACKAGE_NAME +
".RECIEVER";
public static final String RESULT_DATA_KEY = PACKAGE_NAME + ".RESULT_DATA_KEY";
public static final String LOCATION_DATA_EXTRA = PACKAGE_NAME +
".LOCATION_DATA_EXTRA";
}
protected ResultReceiver mReceiver;
public FetchAddressIntentService()
{
super("FetchAddressIntentService");
}
private void deliverResultToReceiver(int resultCode, String message){
Bundle bundle = new Bundle();
bundle.putString(Constants.RESULT_DATA_KEY, message);
mReceiver.send(resultCode,bundle);
}
#Override
protected void onHandleIntent (Intent intent) {
Log.d(TAG, "GeoCoder Service Started");
Geocoder geocoder = new Geocoder(this, Locale.getDefault());
String errorMessage = "";
Location location = intent.getParcelableExtra(Constants.LOCATION_DATA_EXTRA);
List<Address> addresses = null;
try {
addresses = geocoder.getFromLocation(
location.getLongitude(),
location.getLatitude(),
1);
}catch (IOException ioException) {
//catch network or other I/O Problems
errorMessage = getString(R.string.service_not_available);
Log.e(TAG, errorMessage);
} catch (IllegalArgumentException illegalArgumentException){
//catch invalid latitude or longitude values
errorMessage = getString(R.string.invalid_lat_long_used);
Log.e(TAG, errorMessage + "." + "Latitude =" + location.getLatitude()
+ ", Longitude = " + location.getLongitude(),
illegalArgumentException);
}
//handle cases where no addresses was foudn
if (addresses == null || addresses.size() == 0)
{
if(errorMessage.isEmpty()){
errorMessage = getString(R.string.no_address_found);
Log.e(TAG,errorMessage);
}
deliverResultToReceiver(Constants.FAILURE_RESULT, errorMessage);
}else
{
Address address = addresses.get(0);
ArrayList<String> addressFragments = new ArrayList<String>();
//Fetch the address lines using getAddressLine
//join them and send them to the thread
for(int i = 0; i < address.getMaxAddressLineIndex(); i++){
addressFragments.add(address.getAddressLine(i));
}
Log.i(TAG, getString(R.string.address_found));
deliverResultToReceiver(Constants.SUCCESS_RESULT,
TextUtils.join(System.getProperty("line.seperator"), addressFragments));
}
}
}
EDIT: I have tried rewriting the geocoder following the instructions from the android dev site again, but no success.
EDIT2: I noticed in the manifest I declared the service, within the application declaration, instead of outside, I made the change but to no avail, any insights will be appreciated
I have made small app for Android mobile.
In one situation I am not getting any solution.
Actually my app has small functionality for calling to customer.
So after call ended I need that event of which last number will dialed or which app is runs.
AndroidManifest:
<receiver android:name=".PhoneStateBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE">
</action></intent-filter>
</receiver>
Add following permission:
<uses-permission android:name="android.permission.READ_PHONE_STATE">
</uses-permission>
PhoneStateBroadcastReceiver.java (refactored the code a bit)
package com.mobisys.android.salesbooster;
import com.mobisys.android.salesbooster.database.HelperDatabase;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.provider.ContactsContract.PhoneLookup;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
public class PhoneStateBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = "PhoneStateBroadcastReceiver";
Context mContext;
String incoming_number;
private int prev_state;
#Override
public void onReceive(Context context, Intent intent) {
TelephonyManager telephony = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE); //TelephonyManager object
CustomPhoneStateListener customPhoneListener = new CustomPhoneStateListener();
telephony.listen(customPhoneListener, PhoneStateListener.LISTEN_CALL_STATE); //Register our listener with TelephonyManager
Bundle bundle = intent.getExtras();
String phoneNr = bundle.getString("incoming_number");
Log.v(TAG, "phoneNr: "+phoneNr);
mContext = context;
}
/* Custom PhoneStateListener */
public class CustomPhoneStateListener extends PhoneStateListener {
private static final String TAG = "CustomPhoneStateListener";
#Override
public void onCallStateChanged(int state, String incomingNumber){
if( incomingNumber != null && incomingNumber.length() > 0 )
incoming_number = incomingNumber;
switch(state){
case TelephonyManager.CALL_STATE_RINGING:
Log.d(TAG, "CALL_STATE_RINGING");
prev_state=state;
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
Log.d(TAG, "CALL_STATE_OFFHOOK");
prev_state=state;
break;
case TelephonyManager.CALL_STATE_IDLE:
Log.d(TAG, "CALL_STATE_IDLE==>"+incoming_number);
if((prev_state == TelephonyManager.CALL_STATE_OFFHOOK)){
prev_state=state;
//Answered Call which is ended
}
if((prev_state == TelephonyManager.CALL_STATE_RINGING)){
prev_state=state;
//Rejected or Missed call
}
break;
}
}
}
}
Read more here, Source : http://mobisys.in/blog/2011/09/is-your-call-ended-on-android-phone/