Android Notifications through ADB

廉价感情. 提交于 2020-04-10 04:24:43

问题


I'm writing a shell script that allows you to install an .apk on all android phones connected to a computer in parallel using Terminal. At my company we do tests on many devices and so this makes the installation part must faster.

Question: I'm looking for a way to quickly identify which phones have had the .apk installed via some sort of feedback/notification. Ideally you should be able to see which phones have received the .apk just by looking at it (some sort of sound or screen flash) or simply by unlocking the device (ex. the newly installed app has been opened).

Any ideas of how I could do either of these things?

I've read about launching apps but it seems like thats not something you could do with just the .apk (you would also need to specify an activity...).

Any ideas would be much appreciated!

Thanks!


回答1:


Found my own solution!

I was using:

aapt dump badging

thinking that this would just output the package name. Turns out it outputs a lot more of useful info. One of the lines I noticed was output is the launch activity of the app. I was able to isolate this line with grep and then cut out the launch activity as so:

aapt dump badging $1 | grep launchable | cut -d "'" -f 2

Then there is a command that allows you to launch an app if you know one of it's activities. Adding this line launches the activity that was retrieved using the above command.

adb -s $deviceID shell am start -a android.intent.action.MAIN -n $packageName/$launchableActivity

I placed this line in my for loop right after the install command. No after the app is installed the script will attempt to launch it afterwards. Very handy!

Thanks for all the help! :D




回答2:


Use the package manager to check if the APK is installed:

pm list packages [-f] [-d] [-e] [-s] [-3] [-i] [-u] [FILTER]

pm list packages: prints all packages, optionally only
  those whose package name contains the text in FILTER.  Options:
    -f: see their associated file.
    -d: filter to only show disbled packages.
    -e: filter to only show enabled packages.
    -s: filter to only show system packages.
    -3: filter to only show third party packages.
    -i: see the installer for the packages.
    -u: also include uninstalled packages.

for example

$ adb shell pm list packages com.example.mypkg



回答3:


You can use the 'adb shell am start' with arguments you will need to look up to start your newly installed package.

If there's any concern about not being confused by a stale one, adb uninstall the old one before installing the new one, or better yet have your splash activity display versioning.

You can actually use am start to launch an activity which isn't known to the launcher, so you could use it to launch directly to an "about" activity which would display the current version. Your choice if you make that available in the ordinary course of the application, or only use it this one time as a splash.

You should also be able to parse the output of the adb install command - you'll have to see if it sends errors / success to stderr or stdout.

UPDATE: Here's how to make an activity which you can use to turn the screen on and display a message, like this:

adb shell 'am start -n com.example.testreport/.ReportActivity -e result PASS'

The code is heavily cribbed from the built in AlarmClock of an early android version, it will require:

<uses-permission android:name="android.permission.WAKE_LOCK"/>

in the manifest

package com.example.testreport;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.PowerManager;
import android.util.Log;
import android.view.Gravity;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.widget.TextView;
public class ReportActivity extends Activity {
    PowerManager.WakeLock sScreenWakeLock;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
         requestWindowFeature(android.view.Window.FEATURE_NO_TITLE);
         getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
    }
    protected void onStart() {
        super.onStart();

        if (sScreenWakeLock == null) {
            PowerManager pm =
                    (PowerManager) getSystemService(Context.POWER_SERVICE);
            sScreenWakeLock = pm.newWakeLock(
                    PowerManager.FULL_WAKE_LOCK |
                    PowerManager.ACQUIRE_CAUSES_WAKEUP |
                    PowerManager.ON_AFTER_RELEASE, "ReportActivity Wakelock");
            sScreenWakeLock.acquire();
        }
        TextView tv=new TextView(this);
        tv.setTextSize(30);
        tv.setGravity(Gravity.CENTER);
        Intent i = getIntent();
        if ((i != null) && (i.hasExtra("result"))) 
            tv.setText(i.getStringExtra("result"));
        else 
            tv.setText("???");
        setContentView(tv);
    }
    protected void onStop() {
        if (sScreenWakeLock != null) {
            sScreenWakeLock.release();
            sScreenWakeLock = null;
        }
        super.onStop();
    }
}

It can probably use some cleanup and improvement; for example at the moment you can't turn the phone off with the power button unless you first stop the activity by navigating away to make it lose visibility.




回答4:


One way i could see this being done is an application that verifies the installation of the applications. Specifically a checklist of applications that should be installed on the device and as the PackageManager finishes the installation, it updates based on this broadcast.

Aside from doing it outside of the App layer, I don't think its possible unless you sniff the USB port that is going to the device and identify the commands and payload and figure that out (HACK)



来源:https://stackoverflow.com/questions/11355417/android-notifications-through-adb

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!