Can't reinstall crashed Sony SmartWatch Control - java

I hope this is not to generic but I am developing an app for the Sony SmartWatch. When ever I make a mistake like allowing a null pointer exception. I can not get my app to restart. It's like it stays in the crashed state forever. To make the problem worse I also stop receiving messages via Logcat pertaining the app. When I uninstall and reinstall the app It's not listed in the SmartWatch app on the phone. Like it won't register. This is difficult to trouble shoot since I don't get any Log messages at this point. The only thing I can do is uninstall the app. Restart my phone. Then reinstall the app. At that point it's back to normal and I can start writing code again. So that brings me to my questions.
Is there a better way to re-register a control?
Will this happen to end users? If the app crashes will they need to uninstall, reboot and install to recover?
Some Detail (names have been changed to protect the inocent):
I have created a Broadcast Reciever and in my mainfest set it to listen for these broadcasts.
<receiver android:name=".MyExtensionReceiver" >
<intent-filter>
<!-- Receiver intents -->
<action android:name="com.sonyericsson.extras.liveware.aef.registration.EXTENSION_REGISTER_REQUEST" />
<action android:name="com.sonyericsson.extras.liveware.aef.registration.ACCESSORY_CONNECTION" />
<!-- Control intents -->
<action android:name="com.sonyericsson.extras.aef.control.START" />
<action android:name="com.sonyericsson.extras.aef.control.STOP" />
<action android:name="com.sonyericsson.extras.aef.control.PAUSE" />
<action android:name="com.sonyericsson.extras.aef.control.RESUME" />
<action android:name="com.sonyericsson.extras.aef.control.ERROR" />
<action android:name="com.sonyericsson.extras.aef.control.TOUCH_EVENT" />
<action android:name="com.sonyericsson.extras.aef.control.SWIPE_EVENT" />
</intent-filter>
Code for MyExtensionReceiver:
public class MyExtensionReceiver extends BroadcastReceiver {
public MyExtensionReceiver() {
super();
Log.d("mytag", "MyExtensionReceiver Loaded");
Dbg.setLogTag("mytag");
}
#Override
public void onReceive(Context context, Intent intent) {
Log.d("mytag", "onReceive: " + intent.getAction());
intent.setClass(context, MyExtensionReceiver.class);
context.startService(intent);
}
}
Even if my app is crashing I should still get a log message when onReceive is called. It's like the EXTENSION_REGISTER_REQUEST broadcast never gets sent. I just keep uninstalling rebooting and reinstalling over and over. Eventually the app gets found by the SmartConnect App.

It doesn't seem to have anything to do with the BroadcastReceiver. Without using one, I'm having the same annoying problem. I need to restart the phone in order to get things running normal again, as neither disabling/enabling the app helps a bit, nor killing the SmartWatch phone app (as I see no other way to restart it).
I would also appreciate some help from Sony on this matter.

Just came across this issue, giving some grey!! To work around this issue, just create a new intent using string and launch that with context.
Intent intent = new Intent("MY.PACKAGE.NAME.MyExtensionReceiver");
context.startService(intent);

Related

Android Studio - getting PreciseCallState of phone calls

I'm trying to build an Android app in Android Studio to detect the precise call state of outgoing calls. I'm new to Java, and I'm going around in circles with a few problems.
The basic calls states are working fine for me per this youtube guide https://www.youtube.com/watch?v=rlzfcqDlovg. That tutorial uses "TelephonyManager.EXTRA_STATE" in its main class and the "android.intent.action.PHONE_STATE" receiver in the AndroidManifest. It successfully detects when an outgoing call is placed and ended, but NOT when it actually starts ringing/is answered/etc.
I'm trying to get the PreciseCallState of outgoing calls using a couple of StackOverFlow guides like this one How to Use PreciseCallState and other similar discussions, but I'm stuck with a few points:
The basic receiver in AndroidManifest worked fine listening to "android.intent.action.PHONE_STATE". But my precise receiver, listening to "android.intent.action.PRECISE_CALL_STATE" doesn't fire at all, when a call is placed, answered, ended etc.
Even if my receiver DID fire when the PRECISE_CALL_STATE changed, Android Studio doesn't recognize "TelephonyManager.EXTRA_FOREGROUND_CALL_STATE", and won't let me build the app when I try to use this line. I've tried using several "Hidden API bypass" scripts like this one https://github.com/LSPosed/AndroidHiddenApiBypass, but with no luck - I'm unsure how exactly to use this, as the instructions on these type of resources aren't clear to me. All I can figure out is to include their dependencies and "import" the package, not how to actually use it in my script.
Other points:
I know that Google introduced restrictopms on non-standard packages (including reflection) in API level 28 (refer https://developer.android.com/guide/app-compatibility/restrictions-non-sdk-interfaces, so I've tried using API/SDK versions 25 through 32, all with no luck. My current attempt is using SDK version 30.
I've installed my app as a system app using Magisk Systemizer, per other Stackoverflow suggestions for using PreciseCallState, but this didn't fix my issues.
The app doesn't ask for the "READ_PRECISE_PHONE_STATE" permission at all, either when it's installed as a system app or a regular app. I'm not sure if this is okay, but I imagine I'm missing something.
I'd appreciate any help on these 2 issues, I've been trying to research and figure this out for a solid week now!
My code:
AndroidManifest:
<uses-permission android:name="android.permission.READ_PRECISE_PHONE_STATE" />
<application...
...
<receiver android:name=".CallReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<!-- (unused) <action android:name="android.intent.action.PHONE_STATE" />-->
<action android:name="android.intent.action.PRECISE_CALL_STATE" />
<!-- (unused) <action android:name="android.intent.action.NEW_OUTGOING_CALL" />-->
</intent-filter>
</receiver>
</application>
MainActivity:
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PRECISE_PHONE_STATE)
!= PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.READ_PRECISE_PHONE_STATE},1);
}
CallReceiver:
public class CallReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String myString = "new PreciseCallState detected...";
Toast.makeText(context, myString, Toast.LENGTH_LONG).show();
//String myPreciseCallState = intent.getIntExtra(TelephonyManager.EXTRA_FOREGROUND_CALL_STATE, -2);
//Toast.makeText(context, myString + myPreciseCallState, Toast.LENGTH_LONG).show();
// (unused) //String basicCallState = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
}
}

Run function when app is closed - Android

I want to show the user constantly an ongoing notification that doesn't disappear when the user kills the app in the "task manager". The problem is that when this happens (the user kills the app in the "task manager") the ongoing notification disappears. As a solution, I want to resend the notification when the app gets killed by the user or from android itself. I tried to handle this with a BroadcastReciever connected with the PACKAGE_RESTARTED action (like suggested in this post), but it doesn't work (the sysout doesn't get called). Any solutions?
My BroadcastReciever:
package com.appstiq.flutter_app;
public class AutoConnection extends android.content.BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
/*This function should be called when the app is killed
so that I can resend the notification */
System.out.println("It works!");
}
}
Part of my AndroidManifest.xml:
<receiver android:name="com.appstiq.flutter_app.AutoConnection">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_RESTARTED"/>
<data android:scheme="package" android:path="com.appstiq.flutter_app"/>
</intent-filter>
</receiver>
I look forward to helpful answers :D

Android app not receiving FCM push notification from Python Server (iOS is)

I'm working on making an Android version of an iOS app I made earlier this year.
I have a Python Flask API that is supposed to send a push notification via Firebase Cloud Messaging to Android and iOS devices when a certain endpoint is called.
My iOS app is working perfectly, but on Android I don't receive any notifications (neither in foreground nor background).
In my Python code, I'm using a MulticastMessage:
push_notification = messaging.MulticastMessage(
device_tokens,
notification=messaging.Notification(title=title, body=message),
data=data,
apns=messaging.APNSConfig(
payload=messaging.APNSPayload(
messaging.Aps(sound="default")
)
),
android=messaging.AndroidConfig(
notification=messaging.AndroidNotification(
sound="default"
)
)
)
response = messaging.send_multicast(push_notification)
device_tokens is a list of the registration tokens of the devices I want to send the notification to. I verified that one of the tokens is, indeed, the token that my Android Client is using.
data is a dictionary of the following form:
{
"uid": "<user-uid-here>"
}
On the client side, I tried to follow the documentation pretty closely. I added my google-services.json file, added and applied the plugin in the Gradle files, and added the Firebase Messaging dependency. Then I created a Messaging Service and updated my app manifest:
MessagingService.java
public class MessagingService extends FirebaseMessagingService {
public MessagingService() {
super();
}
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
Log.w("Debug", "RECEIVED MESSAGE");
}
}
AndroidManifest.xml
<!--Inside application tag-->
<service
android:name=".model.MessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="#mipmap/ic_launcher" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="#color/colorAccent" />
I should mention that at some point it was sort of working (sometimes I would get the notification, sometimes I wouldn't), but I can't remember exactly what I did that broke it (if I did do anything at all).
I've Googled in a lot of places, but nothing seems to be working.
Am I missing something? I'm pretty confident the problem is not with the server, since the iOS app is handling the notifications just fine.
NOTE: I want to be able to receive messages from both foreground and background state.
EDIT: I am running this on an emulator; perhaps that might be related to the problem? I remember sometimes before the device wouldn't get the notification for a long time...

How to pause onCreate until boot completed?

I host widgets in my app and it seems, that if i start my app before booting of the device is completed, widgets cannot be created properly. Widgets then seem to be not loaded completely or not initialized/updated correctly. For instance: BatteryBotIndicator-Widget, which shows the battery status in percentage, shows a value of "XX" instead of some number like "70%". If i then restart my app and try to recreate the widget with:
AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);
it gives me null for appWidgetInfo (i fetch appWidgetId from SQLite database). And widget cannot be recreated.
It is kind of difficult to debug the real cause in this situation to find out what is exactly causing this (Starting Debugger at the right time). I assume the AppWidgetManager is not ready yet or something.
What i can say for sure: If i wait until i receive the broadcast-event BOOT_COMPLETED all widgets are created properly.
So how can i pause the execution of onCreate until booting is completed?
I can think of putting the thread to sleep in a while loop until the BroadcastReceiver (BOOT_COMPLETED) is setting a bool-variable in application-data to true. But i dont want to wait for this event always at starting of my app, as you can imagine ;)
if i start my app before booting of the device is completed, widgets cannot be created properly.
please explain more what exactly do you mean when you say - "not properly" . this might be relevant to understand if you're widget really depends on something related to the boot.
I can think of putting the thread to sleep in a while loop until the BroadcastReceiver (BOOT_COMPLETED) is setting a bool-variable in application-data to true
very bad idea.. also from performances and design reasons
instead, why not simply register to boot complete broadcast from the manifest, and when you recevice it - simply send the relevant broadcast to update your widget? AppWidgetProvider is already extends BroadcastReceiver, so you can simply add it intent filter for boot complete broadcast.
this is how to add intent filter to boot complete:
<receiver android:name="MyWidgetProvider" >
<intent-filter >
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
<meta-data
...
</receiver>
and this is how to react to it from the widget provider implementation:
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals("android.intent.action.BOOT_COMPLETED")){
doTheUpdateHereExactlyLikeHowYouUpdateItFromAnywhereElse();
} else {
super.onReceive(context,intent);
}
}
for more information - follow this tutorial :https://laaptu.wordpress.com/2013/08/12/android-update-app-widget-with-listview-after-phone-reboot/

Broadcast Receiver not receiving BOOT and MEDIA_MOUNTED intent

I'm trying to create a simple BroadcastReceiver that can receive the android.intent.action.BOOT_COMPLETED intent as well as the android.intent.action.MEDIA_MOUNTED intent. The idea is to start a service on receiving either of these intents. Thus the service should be started after Android boot is complete or when an USB storage device is connected to the Android target(if the service is not already started by then).
Permissions used by the application are defined in this section
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
The following section defines the BroadcastReceiver responsible for handling the intents and starting the corresponding service.
<receiver
android:name="com.example.systemupgradeapplication.IntentReceiver"
android:label="USB Detection Receiver"
android:enabled="true"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED" >
<intent-filter>
<action android:name="android.intent.action.MEDIA_REMOVED" />
<action android:name="android.intent.action.MEDIA_EJECT" />
<action android:name="android.intent.action.MEDIA_BAD_REMOVAL" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MEDIA_MOUNTED" />
<data android:scheme="file" />
</intent-filter>
<intent-filter android:priority="999" >
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
The corresponding service that should be started from the Broadcast Receiver is defined in the following section
<service android:name=".SysUpgradeService" />
Note: The receiver and service components are defined within the <application> section of the Android Manifest.
The following snippet is the Class responsible for handling the intents broadcasted
public class IntentReceiver extends BroadcastReceiver {
private final static String TAG = "IntentReceiver";
private static boolean m_UsbInserted = false;
private static boolean m_UsbRemoved = true;
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "LaunchReceiver::ACTION_MEDIA_MOUNTED :: intent received with path= ");
// TODO Auto-generated method stub
//if(intent.)
String action = intent.getAction();
if (action.equals(Intent.ACTION_MEDIA_MOUNTED)) {
String path = intent.getDataString();
if(path.contains("usb")) {
m_UsbInserted = true;
Log.d(TAG, "LaunchReceiver::ACTION_MEDIA_MOUNTED :: intent received with path= "+path);
Intent myIntent = new Intent(context, SysUpgradeService.class);
myIntent.putExtra("path", path);
context.startService(myIntent);
}
}else if(action.equals(Intent.ACTION_BOOT_COMPLETED)) {
Log.d(TAG, "BOOT Completed intent received");
context.startService(new Intent(context, SysUpgradeService.class));
}
The problem I am facing is that none of the intents are arriving at my broadcast receiver(None of the Logs in the IntentReceiver class are being printed in logcat) even though I can see in the Android Debug logs that the BOOT_COMPLETE and MEDIA_MOUNTED intents are being broadcast. Also This application is not starting after android system is booting up.
I appreciate your help in this regard, what may be wrong with my approach and some possible solutions.
Okay, so I pushed the apk to /system/priv-app which is where System Applications which are part of custom ROM are placed. Now I do not need any activity in my application since it is part of the custom ROM and is recognized as a system application. It seems that if your application is a 3rd party application it must have an activity to be able to receive broadcasted intents.
However in this case I have control over the custom ROM source code as well as root access on the device. So both the approaches work
Make your application part of the custom ROM source, build and flash on device.
Get root access on device, push your apk to /system/priv-app (4.4 onwards), reboot and voila!
Make Sure you have atleat one activity present in your Application.From Android 3.1, BroadcastReceiver will not work until the user has manually launched an activity, This is for provide security . once the user runs the app for the first time then your BroadcastReceiver will run always except it does not Force Stop it. Once activity launch at first time your broadcast receiver will run even after reboot your deice.

Categories