This is my first app using service. Getting java.lang.RuntimeException: Unable to start service java.lang.NullPointerException. My intention is to send sms when device is in suspend state.
SENDSMS.java
package com.qualcomm.sendsms;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.util.Log;
import android.view.Menu;
public class SENDSMS extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sendsms);
String phone_num = null;
String sms = null;
String sleep_time = null;
Bundle extras = getIntent().getExtras();
if (extras != null) {
phone_num = extras.getString("Phone_Number");
Log.e("????????????????SEND_SMS", "phno : "+phone_num);
sms = extras.getString("SMS_Body");
Log.e("????????????????SEND_SMS", "sms : "+sms);
sleep_time = extras.getString("Sleep_Time");
Log.e("????????????????Sleep_Time", "sleep_time : "+sleep_time);
Intent myIntent = new Intent(this, sendservicesms.class);
myIntent.putExtra("Phone_Number",phone_num);
myIntent.putExtra("SMS_Body",sms);
myIntent.putExtra("Sleep_Time",sleep_time);
startService(myIntent);
}
finish();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.sendsm, menu);
return true;
}
}
Service : sendservicesms.java
package com.qualcomm.sendsms;
import android.app.IntentService;
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
import android.telephony.SmsManager;
import android.util.Log;
import android.widget.Toast;
public class sendservicesms extends IntentService {
int mStartMode; // indicates how to behave if the service is killed
IBinder mBinder; // interface for clients that bind
boolean mAllowRebind; // indicates whether onRebind should be used
public sendservicesms() {
super("sendservicesms");
}
public void onCreate() {
// The service is being created
}
#Override
protected void onHandleIntent(Intent intent) {
// The service is starting, due to a call to startService()
if(intent!=null) {
Bundle param = intent.getExtras();
if (param != null) {
String phone_no = (String)param.get("Phone_Number");
String sms_body = (String)param.get("SMS_Body");
String sleeptime = (String)param.get("Sleep_Time");
Log.e("????????????????SEND_SMS", "phno : "+phone_no);
Log.e("????????????????SEND_SMS", "sms : "+sms_body);
Log.e("????????????????Sleep_Time", "sleep_time : "+sleeptime);
Long time = Long.parseLong(sleeptime);
Log.e("????????????????time long", "Long_time : "+time);
try {
if(sleeptime!=null && sleeptime.length() > 0){
Thread.sleep(Long.parseLong(sleeptime));
}
Log.e("????????????????Sleep happened well", "sleep_time : "+sleeptime);
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(phone_no, null, sms_body, null, null);
Toast.makeText(getApplicationContext(), "SMS Sent!",
Toast.LENGTH_LONG).show();
} catch (Exception e) {
Toast.makeText(getApplicationContext(),
"SMS faild, please try again later!",
Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
}
}
#Override
public IBinder onBind(Intent intent) {
// A client is binding to the service with bindService()
return mBinder;
}
#Override
public boolean onUnbind(Intent intent) {
// All clients have unbound with unbindService()
return mAllowRebind;
}
#Override
public void onRebind(Intent intent) {
// A client is binding to the service with bindService(),
// after onUnbind() has already been called
}
#Override
public void onDestroy() {
// The service is no longer used and is being destroyed
}
}
LOGCAT:
E/AndroidRuntime(10276): FATAL EXCEPTION: main
E/AndroidRuntime(10276): java.lang.RuntimeException: Unable to start service com.qualcomm.sendsms.sendservicesms#418dd170 with Intent { cmp=com.qualcomm.sendsms/.sendservicesms (has extras) }: java.lang.NullPointerException
E/AndroidRuntime(10276): at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2676)
E/AndroidRuntime(10276): at android.app.ActivityThread.access$1900(ActivityThread.java:144)
E/AndroidRuntime(10276): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1334)
E/AndroidRuntime(10276): at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(10276): at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime(10276): at android.app.ActivityThread.main(ActivityThread.java:5074)
E/AndroidRuntime(10276): at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(10276): at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(10276): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
E/AndroidRuntime(10276): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
E/AndroidRuntime(10276): at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime(10276): Caused by: java.lang.NullPointerException
E/AndroidRuntime(10276): at android.app.IntentService.onStart(IntentService.java:116)
E/AndroidRuntime(10276): at android.app.IntentService.onStartCommand(IntentService.java:130)
E/AndroidRuntime(10276): at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2659)
You must call the super.onCreate() in the first line inside onCreate() if you override it, Cause system needs to be prepared before your own oncreate() implementation.....
Your program will be running fine if you do that
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Your rest of codes
}
When you remove onCreate() from your Activity, System will do that itself for you. :)
whenever there is a null pointer exception it is mostly due to xml... Some element may not be matching in your xml file.
to send sms u may try the following code:
Intent sendIntent = new Intent(Intent.ACTION_VIEW);
sendIntent.putExtra("sms_body", sms_text_string);
sendIntent.setType("vnd.android-dir/mms-sms");
startActivity(sendIntent);
Related
I am making an app that make something happen when the phone gets a call, so after a lot of searching I discover that I can use a BroadcastReceiver and a Service so I created a Service called PhoneStateService:
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.telephony.TelephonyManager;
import android.widget.Toast;
public class PhoneStateService extends Service {
private static BroadcastReceiver broadcastReceiver;
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
registerBroadcastReceiver();
}
#Override
public void onDestroy() {
unregisterReceiver(broadcastReceiver);
broadcastReceiver = null;
}
private void registerBroadcastReceiver() {
broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String stateStr = intent.getExtras().getString(TelephonyManager.EXTRA_STATE);
if(stateStr.equals(TelephonyManager.EXTRA_STATE_RINGING)){
new PhoneStateHandler().onIncomingCallStarted(context);
}
}
};
IntentFilter filter = new IntentFilter(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
filter.addAction(Intent.ACTION_SCREEN_OFF);
registerReceiver(broadcastReceiver, filter);
}
}
This is the code for starting PhoneStateService(inside MainActivity):
if(PermissionChecker.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) == PermissionChecker.PERMISSION_GRANTED) {
startService(new Intent(getApplicationContext(), PhoneStateService.class));
}
part from the Manifest file:
<service android:name=".Service.PhoneStateService" />
When the phone gets a call and the app is running (it's still didn't Destroy) everything is working good but after I close the app and the phone gets a call the app crash and give me the message that the app has stop working.
please tell me what is the problem, I didn't find answer.
Edit:
The Exception:
09-11 10:26:30.598 29461-29461/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.multiplies.multiring, PID: 29461
java.lang.RuntimeException: Error receiving broadcast Intent { act=android.intent.action.SCREEN_OFF flg=0x50000010 } in com.multiplies.multiring.Service.PhoneStateService$1#1924f18
at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:891)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.os.Bundle.getString(java.lang.String)' on a null object reference
at com.multiplies.multiring.Service.PhoneStateService$1.onReceive(PhoneStateService.java:36)
at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:881)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Edit:
I did what some people said:
String stateStr = intent.getExtras() != null ? intent.getExtras().getString(TelephonyManager.EXTRA_STATE) : "";
put the this doesn't fix the problem.
I thought it won't work because if the intent.getExtras() is returning null, then the if statement won't work because it's returning null and it's want TelephonyManager.EXTRA_STATE_RINGING:
if(stateStr.equals(TelephonyManager.EXTRA_STATE_RINGING)){
new PhoneStateHandler().onIncomingCallStarted(context);
}
but thank you for your help.
HUGE EDIT:
part of the Manifest:
<service android:name=".PhoneState.PhoneStateService" />
<receiver android:name=".PhoneState.PhoneStateBroadcast">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
PhoneStateBroadcast:
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.TelephonyManager;
import android.util.Log;
public class PhoneStateBroadcast extends BroadcastReceiver {
Context context;
public void onReceive(Context context, Intent intent) {
this.context = context;
try {
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Service.TELEPHONY_SERVICE);
switch (telephonyManager.getCallState()) {
case TelephonyManager.CALL_STATE_RINGING:
context.startService(new Intent(context, PhoneStateService.class));
break;
}
} catch (Exception e) {
Log.e("Phone Receive Error", " " + e);
}
}
}
PhoneStateService:
import android.app.IntentService;
import android.content.Intent;
public class PhoneStateService extends IntentService {
public PhoneStateService(String name) {
super(name);
}
#Override
protected void onHandleIntent(Intent intent) {
new PhoneStateHandler().onIncomingCallStarted(getApplicationContext());
}
}
after this edit I am still getting crash.
For some reason the extra's are empty. You are doing intent.getExtras().XXX but intent.getExtras() returns null, calling .XXX on it throws an error.
Changing
String stateStr = intent.getExtras().getString(TelephonyManager.EXTRA_STATE);
into
String stateStr = intent.getExtras() != null ? intent.getExtras().getString(TelephonyManager.EXTRA_STATE) : "";
will stop the crash from happening, but you might want to look into what the reason is why you expect extra's but there aren't any in the intent.
instead of Running a service All the time, make it a BroadcastReciever which is fired whenever the call state is changed.(Running service for a long period of time is not a good practice) thus by using Broadcast receiver, your service would run exactly when you want.
public class PhoneStateService extends BroadcastReceiver{
public void onReceive(Context context, Intent intent) {
mContext = context;
try {
TelephonyManager tm = (TelephonyManager) context.getSystemService(Service.TELEPHONY_SERVICE);
String deviceId=tm.getDeviceId();
switch (tm.getCallState()) {
case TelephonyManager.CALL_STATE_RINGING: // incoming call
//do something on Incoming call event
break;
case TelephonyManager.CALL_STATE_IDLE: //call Ends
//do something on Idle phone state i.e set your logic if an incoming call is complete then this block would execute.
}
} catch (Exception e) {
Log.e("Phone Receive Error", " " + e);
}
}
}
Then add this broadcastReciever to your Manifest under application tag
<receiver android:name="orbitsys.com.prospect_call.CallerState">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
im trying to open a Gallery with Images/Videos from a specific Folder. I´m using this solution but im getting the error code below and nothing happens. I guess its something abot the Uri but i cant find a solution. Has anyone an Idea how to solve this? I also included "my" code.
03-15 16:30:53.733 21902-22775/de.comidos.fotoapp D/onScanCompleted: Scan completed: content://media/external/images/media/1730
03-15 16:30:53.752 21902-22775/de.comidos.fotoapp D/Instrumentation: checkStartActivityResult() : Intent { act=android.intent.action.VIEW dat=content://media/external/images/media/1730 launchParam=MultiScreenLaunchParams { mDisplayId=0 mFlags=0 } }
03-15 16:30:53.773 21902-22775/de.comidos.fotoapp W/Binder: Binder call failed.
android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=content://media/external/images/media/1730 launchParam=MultiScreenLaunchParams { mDisplayId=0 mFlags=0 } }
at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1839)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1531)
at android.app.Activity.startActivityForResult(Activity.java:4389)
at android.app.Activity.startActivityForResult(Activity.java:4348)
at android.app.Activity.startActivity(Activity.java:4672)
at android.app.Activity.startActivity(Activity.java:4640)
at de.comidos.fotoapp.GalleryViewActivity.onScanCompleted(GalleryViewActivity.java:59)
at android.media.MediaScannerConnection$1.scanCompleted(MediaScannerConnection.java:55)
at android.media.IMediaScannerListener$Stub.onTransact(IMediaScannerListener.java:60)
at android.os.Binder.execTransact(Binder.java:573)
package de.comidos.fotoapp;
import android.app.Activity;
import android.content.Intent;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import java.io.File;
public class GalleryViewActivity extends Activity implements MediaScannerConnection.MediaScannerConnectionClient {
public String[] allFiles;
private String SCAN_PATH ;
private static final String FILE_TYPE = "*/*";
private MediaScannerConnection conn;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gallery);
File folder = new File(Environment.getExternalStorageDirectory().toString()+"/comidos/sent/");
allFiles = folder.list();
// uriAllFiles= new Uri[allFiles.length];
for(int i=0;i<allFiles.length;i++)
{
Log.d("all file path"+i, allFiles[i]+allFiles.length);
}
// Uri uri= Uri.fromFile(new File(Environment.getExternalStorageDirectory().toString()+"/yourfoldername/"+allFiles[0]));
SCAN_PATH= Environment.getExternalStorageDirectory().toString()+"/comidos/sent/"+allFiles[0];
Log.d("SCAN PATH", "Scan Path " + SCAN_PATH);
}
private void startScan()
{
Log.d("Connected","success"+conn);
if(conn!=null)
{
conn.disconnect();
}
conn = new MediaScannerConnection(this,this);
conn.connect();
}
#Override
public void onMediaScannerConnected() {
Log.d("onMediaScannerConnected","success"+conn);
conn.scanFile(SCAN_PATH, FILE_TYPE);
}
#Override
public void onScanCompleted(String path, Uri uri) {
try {
Log.d("onScanCompleted","Scan completed: "+uri );
if (uri != null)
{
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(uri);
startActivity(intent);
}
} finally
{
conn.disconnect();
conn = null;
}
}
#Override
public void onResume(){
super.onResume();
startScan();
}
}
There is no activity on your device that supports ACTION_VIEW of a content Uri for whatever MIME type that content is. There is no requirement for an Android device to have an ACTION_VIEW activity for every possible piece of content.
I'm trying to make a simple app that'll lock the screen of the device when an incoming call is accepted. For this, I'm made a custom device admin with the help of this tutorial. But, when I click the "Enable" button in my app, the Device Policy Manager activity does not open at all! And I get output in the logcat window that says that my ComponentName is invalid. However, I do not find any problems in my project what so ever!
MainActivity.java
package com.swap.delay;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends ActionBarActivity {
DevicePolicyManager devicePolicyManager;
ActivityManager activityManager;
ComponentName componentName;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
devicePolicyManager = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
componentName = new ComponentName(this, LockAdmin.class);
}
public void OnClickActivate(View view) {
Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, componentName);
intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "Lock Admin by Swap");
startActivityForResult(intent, 1);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1 && resultCode == Activity.RESULT_OK) {
Toast.makeText(getBaseContext(), "Lock Admin by Swap added successfully", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getBaseContext(), "Failed!", Toast.LENGTH_SHORT).show();
}
super.onActivityResult(requestCode, resultCode, data);
}
}
LockAdmin.java
package com.swap.delay;
import android.app.admin.DeviceAdminReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.widget.Toast;
public class LockAdmin extends DeviceAdminReceiver{
static SharedPreferences getSamplePreferences(Context context) {
return context.getSharedPreferences(DeviceAdminReceiver.class.getName(), 0);
}
static String PREF_PASSWORD_QUALITY = "password_quality";
static String PREF_PASSWORD_LENGTH = "password_length";
static String PREF_MAX_FAILED_PW = "max_failed_pw";
void showToast(Context context, CharSequence message) {
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
}
#Override
public void onEnabled(Context context, Intent intent) {
showToast(context, "Lock Admin Enabled");
}
#Override
public void onPasswordFailed(Context context, Intent intent) {
showToast(context, "Lock Admin: Wrong Password");
}
#Override
public void onPasswordSucceeded(Context context, Intent intent) {
//showToast(context, "Sample Device Admin: pw succeeded");
}
}
policies.xml
<device-admin xmlns:android="http://schemas.android.com/apk/res/auto">
<uses-policies>
<force-lock>
</force-lock>
</uses-policies>
</device-admin>
Receiver(Added to manifest.xml)
<receiver android:name=".LockAdmin" android:permission="android.permission.BIND_DEVICE_ADMIN">
<meta-data android:name="android.app.device_admin" android:resource="#xml/policies">
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED">
</action></intent-filter>
</meta-data></receiver>
Logcat output -
08-25 12:52:40.103 652-1906/? I/ActivityManager﹕ START u0 {act=android.app.action.ADD_DEVICE_ADMIN cmp=com.android.settings/.DeviceAdminAdd (has extras)} from uid 10172 on display 0
08-25 12:52:40.162 652-1070/? I/ActivityManager﹕ Start proc com.android.settings for activity com.android.settings/.DeviceAdminAdd: pid=6313 uid=1000 gids={41000, 9997, 3002, 3001, 3003, 1028, 1015, 1000, 1021, 3004, 3005, 3009, 1023, 1010, 1007} abi=arm64-v8a
08-25 12:52:40.332 6313-6313/? W/DeviceAdminAdd﹕ Request to add invalid device admin: ComponentInfo{com.swap.delay/com.swap.delay.LockAdmin}
P.s. - I tested out the app on two different devices on based on AOSP KitKat(4.4.2) and another one CyanogenOS 12.0(5.0.2), it didn't work on either of them.
I am starting a foreground service and I am getting a null pointer exception. I'm not getting which is the null reference. I want to download the mp3 from server and show the progress in notification like google play-store does for each application downland.
Does new MyNotification(getApplicationContext() is null?
07-31 14:48:39.504 21210-21210/com.sunil.divine.mybhajans E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.sunil.divine.mybhajans, PID: 21210
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.Context.getApplicationContext()' on a null object reference
at android.content.ContextWrapper.getApplicationContext(ContextWrapper.java:106)
at service.DownloadingService.startForegroundService(DownloadingService.java:47)
at com.sunil.divine.mybhajans.List_songs.itemClick(List_songs.java:104)
at service.SunilAdaptor$MyViewHolder.onClick(SunilAdaptor.java:75)
at android.view.View.performClick(View.java:4780)
at android.view.View$PerformClick.run(View.java:19866)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
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)
Please don't close the question. Please explain to me the proper way to handle this.
Thanks.
Following is itemClick for each row in Listview
#Override
public void itemClick(View view, int position) {
Toast.makeText(this, "On ItemClick", Toast.LENGTH_LONG).show();
Intent intent=new Intent(this, DownloadingService.class);
switch (position){
case 0:
intent.putExtra("position","URL");
//List_songs.java:104 null pointer
new DownloadingService().startForegroundService(position);
break;
case 1:
intent.putExtra("position", "URL");
new DownloadingService().startForegroundService(position);
break;
}
}
following is the DownloadingService() class:
package service;
import android.app.Service;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;
import android.widget.Toast;
import java.util.concurrent.Executor;
/**
* Created by Dell Vostro on 7/19/2015.
*/
public class DownloadingService extends Service {
#Override
public void onCreate() {
Log.w("Inside","--------------Oncreate method-----------");
Toast.makeText(getApplicationContext(),"Inside oncreate",Toast.LENGTH_LONG).show();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.w("Inside","--------------onStartCommand method-----------"+startId);
String url= (String) intent.getExtras().get("position");
String param[]={url};
//task to download the mp3
new DownloadFilesTask(this,startId).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,param);
// Toast.makeText(getApplicationContext(),"Inside onStartCommand"+pos,Toast.LENGTH_LONG).show();
return START_STICKY;
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
super.onDestroy();
}
public void startForegroundService(int position){
//DownloadingService.java:47 null pointer here
startForeground(position,new MyNotification(getApplicationContext()).createNotification(position));
}
}
following is class to generate notification:
package service;
import android.app.Activity;
import android.app.NotificationManager;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
import com.sunil.divine.mybhajans.R;
/**
* Created by Dell Vostro on 7/30/2015.
*/
public class MyNotification {
private int position;
private Context context;
private NotificationManager mNotifyManager;
private NotificationCompat.Builder mBuilder;
public MyNotification() {
}
public MyNotification(Context context) {
this.context=context;
}
public android.app.Notification createNotification(int position) {
mNotifyManager =
(NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
mBuilder = new NotificationCompat.Builder(context);
mBuilder.setContentTitle("Song Download")
.setContentText("Download in progress")
.setSmallIcon(R.mipmap.ic_launcher);
// Sets the progress indicator to a max value, the
// current completion percentage, and "determinate"
// state
mBuilder.setProgress(100, new DownloadFilesTask().getCalculatedProgress(), false);
// Displays the progress bar for the first time.
mNotifyManager.notify(position, mBuilder.build());
return mBuilder.build();
}
// Update the progress bar
public void updateNotification(int calculatedProgress,int startId){
mBuilder.setProgress(100, calculatedProgress, false);
mNotifyManager.notify(startId, mBuilder.build());
}
}
Well, your issue is that's not how you start a service in the foreground. You should read about Android Services, their lifecycle, and how to start a service. Your code contains several fundamental mistakes.
Take a look at this example for how to launch a foreground service
In terms of what's specifically wrong with your code, the simplest explanation is that, you should start an intent that starts the service then within the service (while it is running and has correct context), call startforeground. Instead, you create an object and call startforeground from within your application.
I am new to android + bluetooth. I am trying to write a simple rfcomm client app which talks to a rfcomm server running on a embedded platfrom. When my application starts it show a listview of paired devices and on clicking one of thoes devices it jumps to a second activity. In this activity I opens a bluetooth socket and connects to it. As soon as I jump to a new activity my UI sort of hangs. This new activity has two buttons. Onclick of these buttons I send data to bluetooth server. But my UI kind of hangs in this activity, once I click a button it takes ages to respond and it generates a error message.
My codes looks like this:
package com.example.bluetoothapp2;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Set;
import java.util.UUID;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
// Return Intent extra
public static String EXTRA_DEVICE_ADDRESS = "device_address";
public int REQUEST_ENABLE_BT = 1;// Just defining a flag
//Define a local bluetooth adapter variable to get id of default Adapter
public BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
//Adapter for LIST ITEMS FOR PAIRED DEVICES
public ArrayAdapter<String> mPairedDevicesArrayAdapter;
//Array to store list data for paired device
ArrayList<String> itemPairedArray = new ArrayList<String> ();
//Adapter for LIST ITEMS FOR NEW DEVICES
public ArrayAdapter<String> mNewDevicesArrayAdapter;
//Array to store list data for paired device
ArrayList<String> itemNewDvcArray = new ArrayList<String> ();
//RECORDING HOW MUCH TIMES BUTTON WAS CLICKED
int clickCounter=0;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
private void init()
{
//GetListId from Layout
ListView pairedListView = (ListView) findViewById(R.id.listPairedDvc);
ListView newListView = (ListView) findViewById(R.id.listAvailableDvc);
//Bind the list with listview in layout
mPairedDevicesArrayAdapter= new ArrayAdapter<String>(this,android.R.layout.simple_expandable_list_item_1,itemPairedArray);
mNewDevicesArrayAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_expandable_list_item_1,itemNewDvcArray);
//Set the adapter to list view (bind a adapter to listview in layout)
pairedListView.setAdapter(mPairedDevicesArrayAdapter);
newListView.setAdapter(mNewDevicesArrayAdapter);
pairedListView.setOnItemClickListener(mDeviceClickListener);
// Register the BroadcastReceiver
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter); // Don't forget to unregister during onDestroy
// Register for broadcasts when discovery has finished
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
this.registerReceiver(mReceiver, filter);
// Register for broadcasts when discovery has finished
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
this.registerReceiver(mReceiver, filter);
// Get a set of currently paired devices
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
// If there are paired devices, add each one to the ArrayAdapter
if (pairedDevices.size() > 0)
{
/*findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);*/
for (BluetoothDevice device : pairedDevices)
{
itemPairedArray.add(device.getName() + " => "+ device.getAddress());
}
}
else
{
itemPairedArray.add("noDevices");
}
//Check if device has bluetooth
if(mBluetoothAdapter == null)
{
Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_LONG).show();
finish();
return;
}
//Check if it is enabled or not
if(!mBluetoothAdapter.isEnabled())
{
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
}
//METHOD WHICH WILL HANDLE DYNAMIC INSERTION
public void addItems(View v)
{
//itemPairedArray.add("Clicked : "+clickCounter++); //Just for debugging
//itemNewDvcArray.add("Clicked : "+clickCounter++); //Just for debugging
//itemNewDvcArray.add("NoDevice");
startDiscovery() ;
//mPairedDevicesArrayAdapter.notifyDataSetChanged();
mNewDevicesArrayAdapter.notifyDataSetChanged();
}
//method to start discovery
private void startDiscovery()
{
// TODO Auto-generated method stub
// If we're already discovering, stop it
if (mBluetoothAdapter.isDiscovering())
{
mBluetoothAdapter.cancelDiscovery();
}
// Request discover from BluetoothAdapter
mBluetoothAdapter.startDiscovery();
}
protected void onDestroy()
{
super.onDestroy();
// Make sure we're not doing discovery anymore
if (mBluetoothAdapter != null)
{
mBluetoothAdapter.cancelDiscovery();
}
// Unregister broadcast listeners
this.unregisterReceiver(mReceiver);
}
// The BroadcastReceiver that listens for discovered devices and
// changes the title when discovery is finished
private final BroadcastReceiver mReceiver = new BroadcastReceiver()
{
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action))
{
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// If it's already paired, skip it, because it's been listed already
if (device.getBondState() != BluetoothDevice.BOND_BONDED)
{
// Add the name and address to an array adapter to show in a ListView
itemNewDvcArray.add(device.getName() +" => "+ device.getAddress());
}
}
}
};
// The on-click listener for all devices in the ListViews
private OnItemClickListener mDeviceClickListener = new OnItemClickListener()
{
public void onItemClick(AdapterView<?> av, View v, int arg2, long arg3)
{
// Get the device MAC address, which is the last 17 chars in the View
String info = ((TextView) v).getText().toString();
String address = info.substring(info.length() - 17);
//Toast.makeText(getApplicationContext(), address, 0).show();
// Create the result Intent and include the MAC address
Intent intent = new Intent(MainActivity.this,ConnectActivity.class);
intent.putExtra(EXTRA_DEVICE_ADDRESS, address);
startActivity(intent);
}
};
}
package com.example.bluetoothapp2;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class ConnectActivity extends Activity {
// Unique UUID for this application
public static final UUID MY_UUID_INSECURE = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
String address;
protected static final int SUCCESS_CONNECT = 0;
protected static final int MESSAGE_READ = 1;
public BluetoothSocket mmSocket;
public InputStream mmInStream;
public OutputStream mmOutStream;
String tag = "debugging";
private BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
Handler mHandler = new Handler(){
#Override
public void handleMessage(Message msg)
{
// TODO Auto-generated method stub
Log.i(tag, "in handler");
super.handleMessage(msg);
switch(msg.what){
case SUCCESS_CONNECT:
// DO something
ConnectedThread connectedThread = new ConnectedThread((BluetoothSocket)msg.obj);
//Toast.makeText(getApplicationContext(), "CONNECT", 0).show();
String s = "successfully connected";
connectedThread.write(s.getBytes());
Log.i(tag, "connected");
break;
case MESSAGE_READ:
byte[] readBuf = (byte[])msg.obj;
String string = new String(readBuf);
//Toast.makeText(getApplicationContext(), string, 0).show();
break;
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_connect);
// Get the message from the intent
Intent intent = getIntent();
address = intent.getStringExtra(MainActivity.EXTRA_DEVICE_ADDRESS);
// Create the text view
TextView textView = (TextView)findViewById(R.id.addrs);
//textView.setTextSize(40);
textView.setText(address);
connect();
}
//method to start discovery
public void connect()
{
// Get the BluetoothDevice object
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
//Toast.makeText(getApplicationContext(),"connecting", 0).show();
ConnectThread connect = new ConnectThread(device) ;
connect.start();
}
//Thread for establising a connection
private class ConnectThread extends Thread
{
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
public ConnectThread(BluetoothDevice device)
{
// Use a temporary object that is later assigned to mmSocket,
// because mmSocket is final
BluetoothSocket tmp = null;
mmDevice = device;
// Get a BluetoothSocket to connect with the given BluetoothDevice
try {
// MY_UUID is the app's UUID string, also used by the server code
tmp = device.createRfcommSocketToServiceRecord(MY_UUID_INSECURE);
} catch (IOException e) { }
mmSocket = tmp;
}
public void run()
{
// Cancel discovery because it will slow down the connection
mBluetoothAdapter.cancelDiscovery();
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mmSocket.connect();
} catch (IOException connectException) {
// Unable to connect; close the socket and get out
try {
mmSocket.close();
} catch (IOException closeException) { }
return;
}
// Do work to manage the connection (in a separate thread)
//manageConnectedSocket(mmSocket);
mHandler.obtainMessage(SUCCESS_CONNECT, mmSocket).sendToTarget();
}
/** Will cancel an in-progress connection, and close the socket */
public void cancel()
{
try
{
mmSocket.close();
} catch (IOException e) { }
}
}
private class ConnectedThread extends Thread
{
public ConnectedThread(BluetoothSocket socket) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the input and output streams, using temp objects because
// member streams are final
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) { }
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
byte[] buffer ; // buffer store for the stream
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
// Read from the InputStream
buffer = new byte[1024];
bytes = mmInStream.read(buffer);
// Send the obtained bytes to the UI activity
mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer).sendToTarget();
} catch (IOException e) {
break;
}
}
}
/* Call this from the main activity to send data to the remote device */
public void write(byte[] bytes) {
try {
//a delay of 20ms occurs after each flush...
mmOutStream.write(bytes);
mmOutStream.flush();
} catch (IOException e) { }
}
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
//method to start discovery
public void ledOn(View v ) throws IOException
{
//Toast.makeText(getApplicationContext(),"LED ON", 0).show();
mmOutStream.write('o');
}
//method to start discovery
public void ledOff(View v ) throws IOException
{
//Toast.makeText(getApplicationContext(),"LED OFF", 0).show();
mmOutStream.write('f');
}
public void disconnectCntn(View v ) throws IOException
{
String msg = "Disconnect";
mmOutStream.write(msg.getBytes());
// close the connection
mmOutStream.close();
mmInStream.close();
// close the connection
if (mmSocket != null)
try {
mmSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return;
}
}
I get following error messages
08-19 13:09:55.833: D/AndroidRuntime(5221): Shutting down VM
08-19 13:09:55.834: W/dalvikvm(5221): threadid=1: thread exiting with uncaught exception (group=0x41cc29a8)
08-19 13:09:55.847: E/AndroidRuntime(5221): FATAL EXCEPTION: main
08-19 13:09:55.847: E/AndroidRuntime(5221): java.lang.IllegalStateException: Could not execute method of the activity
08-19 13:09:55.847: E/AndroidRuntime(5221): at android.view.View$1.onClick(View.java:3606)
08-19 13:09:55.847: E/AndroidRuntime(5221): at android.view.View.performClick(View.java:4211)
08-19 13:09:55.847: E/AndroidRuntime(5221): at android.view.View$PerformClick.run(View.java:17446)
08-19 13:09:55.847: E/AndroidRuntime(5221): at android.os.Handler.handleCallback(Handler.java:725)
08-19 13:09:55.847: E/AndroidRuntime(5221): at android.os.Handler.dispatchMessage(Handler.java:92)
08-19 13:09:55.847: E/AndroidRuntime(5221): at android.os.Looper.loop(Looper.java:153)
08-19 13:09:55.847: E/AndroidRuntime(5221): at android.app.ActivityThread.main(ActivityThread.java:5299)
08-19 13:09:55.847: E/AndroidRuntime(5221): at java.lang.reflect.Method.invokeNative(Native Method)
08-19 13:09:55.847: E/AndroidRuntime(5221): at java.lang.reflect.Method.invoke(Method.java:511)
08-19 13:09:55.847: E/AndroidRuntime(5221): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
08-19 13:09:55.847: E/AndroidRuntime(5221): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
08-19 13:09:55.847: E/AndroidRuntime(5221): at dalvik.system.NativeStart.main(Native Method)
08-19 13:09:55.847: E/AndroidRuntime(5221): Caused by: java.lang.reflect.InvocationTargetException
08-19 13:09:55.847: E/AndroidRuntime(5221): at java.lang.reflect.Method.invokeNative(Native Method)
08-19 13:09:55.847: E/AndroidRuntime(5221): at java.lang.reflect.Method.invoke(Method.java:511)
08-19 13:09:55.847: E/AndroidRuntime(5221): at android.view.View$1.onClick(View.java:3601)
08-19 13:09:55.847: E/AndroidRuntime(5221): ... 11 more
08-19 13:09:55.847: E/AndroidRuntime(5221): Caused by: java.io.IOException: [JSR82] write: write() failed.
08-19 13:09:55.847: E/AndroidRuntime(5221): at android.bluetooth.BluetoothSocket.write(BluetoothSocket.java:702)
08-19 13:09:55.847: E/AndroidRuntime(5221): at android.bluetooth.BluetoothOutputStream.write(BluetoothOutputStream.java:56)
08-19 13:09:55.847: E/AndroidRuntime(5221): at com.example.bluetoothapp2.ConnectActivity.ledOn(ConnectActivity.java:213)
08-19 13:09:55.847: E/AndroidRuntime(5221): ... 14 more
Sorry for such a long post. Any idea why is the UI hangs and what could be causing the error.
Thanks
Tama
ConnectedThread is instantiated, however we have skipped the part which starts the thread, fancy calling start() on it? connectedThread.start() which will keep it listening on a socket for any data written.
ConnectedThread connectedThread = new ConnectedThread((BluetoothSocket)msg.obj);
//add this line
connectedThread.start()
//Toast.makeText(getApplicationContext(), "CONNECT", 0).show();
String s = "successfully connected";
connectedThread.write(s.getBytes());