精华内容
下载资源
问答
  • 应用之星已经免费场景难,但做好看的,这就需要用户自己修炼了!希望下文能对大家有帮助。  你需先了解以下内容: 1.浏览器 请使用chrome浏览器,更新到最新版。我们对chrome浏览器支持最好,其他...

               应用之星已经让做个免费场景不难,但做个好看的,这就需要用户自己修炼了!希望下文能对大家有帮助。

               你需先了解以下内容:

    1.浏览器

    请使用chrome浏览器,更新到最新版。我们对chrome浏览器支持最好,其他浏览器,我们还在加油!

    2.场景文案

    场景制作前,先要策划好文案,你才能为场景定好图片、音乐等调子。一切始于文案!名称和描述就是场景的广告,名称和标题都应当具有吸引力,另外名称比描述重要。

    3.场景图片

    图片好了,你的场景就成功了一半,那么,如何为场景制作好图片?

    图片素材可以从以下渠道获取:

    ①公司内部;

    ②设计师制作;

    ③百度图片搜索;

    ④花瓣等图片设计类网站。

    图片格式:

    ①静态背景图,推荐jpg格式;

    ②动态背景图,使用gif格式。

    图片大小:300KB以内,风景等色彩比较多的背景图,图片质量中高即可。

    图片适配问题:一部分需要场景应用制作平台解决,另一部分需要我们自己解决。

    3.场景动效

    给文字、图片等元素加上动作,就可以变成动效效果,有两种实现方式:

    ①通过应用之星提供的模板来解决,优点是按着模板制作,省时省力;

    ②通过应用之星提供的动效功能来自己设定动态效果,优点是自由度大,可以设计出好看的效果。

    4.背景音乐

    用户访问场景时开始播放音乐,可以增加场景感染力。

    音乐素材如何获得:

    ①百度音乐下载,然后本地上传;

    ②在音乐库查找。

    制作要求:

    ①40秒-1分钟为宜;

    ②节奏适合重复播放;

    ③大小1-2M,不应大于3M,否则用户打开加载时间长然后本地上传体验不好,这跟图片要控制大小一个道理。

    了解完这些后,制作就很简单了。

    以下是app制作步骤。

    1. 进入应用之星网站,注册激活账号并登录;

    2. 点击应用制作——>高级模式——>点“+”创建;你也可以直接使用系统模板;


    3. 进入制作界面,有各种控件使用,根据需要进行选择。你可以使用音乐控件,视频控件,也可以设置动画效果,这样制作出来的效果更酷炫。关于控件的使用,请看教程:应用之星:app开发的控件合集介绍


    4. 当你觉得制作完成后,在发布之前,你可以点开设置,在这里,你可以添加名称、描述、选择类型、翻页方式,翻页效果,播放方式,选择背景音乐,修改封面。

    5. 等你一切制作好后,点击设置—>高级,再选择Android,即可生成安卓app了。其中Web就是指的H5页面。有关H5页面的介绍,请看:http://www.appstar.com.cn/course/290670.html

    6. 点击发布,你将看到预览页面,通过扫描二维码就能下载了。Android即app,Web即H5页面。

    是不是很简单?动手制作一个吧。


    展开全文
  • 理想、梦想的话题被...而一款名为“念”的应用则是用了一个更为极端的方式来用户坚持更新、记录自己的理想清单——如果有一天没有更新,那么你的号就被封了。 听起来好像很凶残的一款应用,用户如何使用它不是自己
    can-the-dream-also-monetize-reading-lets-your-one-day-not-update-confers-a-title-upon-1

    理想、梦想的话题被经常提及,它不但是一个每个人都需要规划实现的事情,同时也是最难坚持的事情之一。像PingWest之前报道的“十年”和“我们的梦想”都是这类的应用服务,他们分别用不同的方式来让用户记录、分享自己的梦想。而一款名为“念”的应用则是用了一个更为极端的方式来让用户坚持更新、记录自己的理想清单——如果有一天没有更新,那么你的号就被封了。

    听起来好像很凶残的一款应用,用户如何使用它不是自己的自由么,为什么还要封我号?其实这正是大部分人在规划自己的生活和梦想中遇到最大的问题:意志力。并非每个人靠自己的意志力都能坚持有规律的做好每一件应该做的事情,哪怕是跑步这件看起来很简单的事,也可能因为天气、心情、疲劳等原因而放弃。这种情况下督促就成为一个关键的推动因素。再想一下,上学的时候老师是不是也用各种各样的方式督促学生呢?而相比起表扬、奖励等激励方式,惩罚似乎督促的效果更加明显,而“念”就是利用这一点,让用户能够持续更新。

    can-the-dream-also-monetize-reading-lets-your-one-day-not-update-confers-a-title-upon-2

    具体来说,“念”有Web端和移动端的应用,UI风格设计十分简约,黑色的风格还有一些沉重。用户能够做的就是发布一条自己的清单,上传照片,配上文字,然后就是每天去更新内容,直到完成这个梦想。同时可以发布多条梦想。而核心的功能在于,无论你是选择更新某一个梦想的进展,还是建立一个新的梦想,只要一天没有更新,那么对不起,你的号码就被停用了。

    这时你只能选择删除梦想,退出账号,或者支付5个“念币”(每天的第一次更新可以获得一个“念币”,或者选择用人民币购买“念币”,当然它不能被反向兑换)来解冻账户。这样的方式唯一的目的就是让用户保持更新的频率与节奏:如果你设定了一项“坚持跑步锻炼身体”的目标,那么不管当天是跑了10公里还是因为下雨所以在家休息,都请记录在“念”中,这样当回顾的时候就能知道自己对于这项目标做到了什么程度。

    IMG_6203

    另外,“念”还可以在平台上发布话题,其他的用户会回复话题,由于话题内容是不会算在更新当中的,所以用户也可以将“念”当成一个小型的留言板来抒发自己的想法。不过在我使用后发现,“念”本身还存在一些比较严重的问题:

    首先就是内容上面,现有的用户几乎没有把“念”当成一个梦想清单管理应用,而是当做一个抒发情感、分享心情的日记软件,并没有将每天的更新变为实现目标的记录,造成这一问题的原因或许是要求每日更新所带来的负面作用——每日更新这一概念更加的贴合日记的功能。

    而移动客户端Bug还比较多,比如UI设计上顶端的按钮与iOS的顶部信息栏重合,比如在回复其他用户的话题时如果点了某个人而不发言的话,点击别的话题留言仍然会默认@上一个用户,同时所有的发出的留言不能删除。

    总的来说,“念”现阶段应该还不足以称为一款好用的产品,Bug和使用场景的不明确很难让用户提起移动端的使用兴趣,倒是Web端使用起来更加方便顺手,但是到底用念来写些什么内容有点让人摸不着头脑。

    不过,这种用停号这种惩罚机制来督促用户规划、完成自己的生活内容不失为一种好的想法。

     

    展开全文
  • 忘记说一个最重要的前提了。 我用的是Android1.6,刚在网上查到了。 是因为SDK的原因。 在1.6下有这个Bug 怎么能把分平分啊? [b]问题补充:[/b] to omett: 没解决啊。 我改变1.5就好用了。。。。 ...
  • 您几乎几乎需要更新create-react-app本身:它将所有设置委派给react-scripts 。 当您运行create-react-app ,它将始终使用最新版本的react-scripts创建项目,因此您将自动获得新创建的应用程序中的所有新功能和...
  • 如果在应用中有一个判断wifi的开关和一个当前音量大小的seekbar以及一个获取当前电量多少的按钮,想知道如果按home键后调整了wifi开关信息以及媒体音量信息,再切换到前台UI如何才会实时刷新。其实这个问题难解决...

    前日,一小伙伴问我一个问题,说它解决了半天都没解决这个问题,截图如下:

     

    大概楼主理解如下:

    如果在应用中有一个判断wifi的开关和一个当前音量大小的seekbar以及一个获取当前电量多少的按钮,想知道如果按home键后调整了wifi开关信息以及媒体音量信息,再切换到前台UI如何才会实时刷新。其实这个问题不难解决,如果你了解activity的生命周期,只需要把设置开关和seekbar的信息放在onResume中就好了,因为无论是锁屏后打开或者是切换后台再前台都是会调用onResume的。但不由得滋生一个问题,大家都知道APP在前台的情况下用户依然是可以下拉状态栏设置Wifi开关信息的,对于音量信息也是可以侧边增减,那APP一直在前台,生命周期明显是无法实时更新了,那我们应该如何解决呢?没错,没当改变系统属性的时候,都会发出系统广播,我们只需要去写一个接收器,并根据它做响应的操作就好了。

     

    分析至此,楼主就把给这位小伙伴写的一些代码分享给大家,也可以帮助不太熟悉的小伙伴更加了解android的广播以及回调机制。对于还不太明白java的回调是什么意思的小伙伴,也可以看看。

     

    1)由于要使用到系统属性,所以先申明权限。

    1 <!--wifi管理必备权限-->
    2     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    3     <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
    4 
    5     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    6 
    7     <!--操作音频需要权限-->
    8     <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>

    2)然后写一个广播接收器,做好过滤,并申明一个回调接口,用于当广播接收到的时候提醒主线程更新UI。

     1 package com.example.nanchen.maweinaitest;
     2 
     3 import android.content.BroadcastReceiver;
     4 import android.content.Context;
     5 import android.content.Intent;
     6 import android.media.AudioManager;
     7 import android.net.wifi.WifiManager;
     8 import android.util.Log;
     9 
    10 import static android.content.Intent.ACTION_BATTERY_CHANGED;
    11 
    12 /**
    13  * @author nanchen
    14  * @fileName MaWeiNaiTest
    15  * @packageName com.example.nanchen.maweinaitest
    16  * @date 2016/11/05  21:35
    17  */
    18 
    19 public class MyStatusReceiver extends BroadcastReceiver {
    20 
    21     private static final String TAG = "MyStatusReceiver";
    22     private StatusCallback mStatusCallback = MainActivity.callback;
    23 
    24     public MyStatusReceiver(){
    25     }
    26 
    27     @Override
    28     public void onReceive(Context context, Intent intent) {
    29 
    30         String action = intent.getAction();
    31         Log.e(TAG,action);
    32         Log.e(TAG,intent.getAction()+" ====   ");
    33 
    34 
    35         // 首先判断它是否是电量变化的Broadcast Action
    36         if (ACTION_BATTERY_CHANGED.equals(action)) {//如果监听到电量改变广播
    37             // 获取当前电量
    38             int level = intent.getIntExtra("level", 0);
    39             // 电量的总刻度
    40             int scale = intent.getIntExtra("scale", 100);
    41             // 把它转换为百分比
    42 //            mActivity.mTextView.setText(level * 100 / scale + "%");
    43             String str = level * 100 / scale + "%";
    44 
    45             Log.e(TAG,level+"");
    46             Log.e(TAG,scale+"");
    47             Log.e(TAG,str+"");
    48 
    49             mStatusCallback.onPowerChanged(level * 100 / scale + "%");
    50         }
    51         // 监听一下音量
    52         if ("android.media.VOLUME_CHANGED_ACTION".equals(action)){
    53 //            mActivity.mSeekBar.setProgress(mActivity.mAudioManager.getStreamVolume(AudioManager.STREAM_SYSTEM));
    54             AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
    55             int progress = audioManager.getStreamVolume(AudioManager.STREAM_SYSTEM);
    56             Log.e(TAG,progress+"");
    57             mStatusCallback.onAudioChanged(audioManager.getStreamVolume(AudioManager.STREAM_SYSTEM));
    58         }
    59         if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)){
    60             WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
    61             mStatusCallback.onWifiChanged(wifiManager.isWifiEnabled());
    62         }
    63     }
    64 
    65     /**
    66      * 一个回调接口
    67      */
    68     public interface StatusCallback {
    69         /**
    70          * 当电量改变时应该调用的回调接口
    71          * @param status 当前电量百分比
    72          */
    73         void onPowerChanged(String status);
    74 
    75         /**
    76          * 当音频音量改变时会调用的回调接口
    77          * @param status 当前音量数值
    78          */
    79         void onAudioChanged(int status);
    80 
    81         /**
    82          * 当wifi改变时会调用的回调接口
    83          * @param status  wifi的开关  true-开   false - 关
    84          */
    85         void onWifiChanged(boolean status);
    86     }
    87 }

    3)别忘了在mainfest申明

    1 <receiver android:name=".MyStatusReceiver">
    2             <intent-filter>
    3                 <action android:name="android.intent.action.BATTERY_CHANGED"/>
    4                 <action android:name="android.media.VOLUME_CHANGED_ACTION"/>
    5                 <action android:name="android.net.wifi.WIFI_STATE_CHANGED_ACTION"/>
    6             </intent-filter>
    7         </receiver>

    4)布局就采用的这位小伙伴的布局

     1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     2               xmlns:tools="http://schemas.android.com/tools"
     3               android:layout_width="match_parent"
     4               android:layout_height="match_parent"
     5               android:orientation="vertical">
     6 
     7 
     8 
     9     <Switch
    10         android:id="@+id/wifi"
    11         android:layout_width="wrap_content"
    12         android:layout_height="wrap_content"
    13         android:textOn="开"
    14         android:textOff="关"
    15         android:text="WiFi"/>
    16 
    17     <SeekBar
    18         android:id="@+id/seekBar"
    19         android:layout_width="match_parent"
    20         android:layout_height="wrap_content"
    21         android:layout_marginTop="16dp"/>
    22 
    23     <Button
    24         android:id="@+id/btn"
    25         android:layout_width="match_parent"
    26         android:layout_height="wrap_content"
    27         android:layout_marginTop="16dp"
    28         android:text="当前电量百分比" />
    29 
    30 
    31     <LinearLayout
    32         android:orientation="horizontal"
    33         android:layout_width="match_parent"
    34         android:layout_height="wrap_content">
    35 
    36         <TextView
    37             android:layout_width="wrap_content"
    38             android:layout_height="wrap_content"
    39             android:text="当前电量百分比为:"/>
    40 
    41         <TextView
    42             android:layout_width="wrap_content"
    43             android:layout_height="wrap_content"
    44             android:text="0%"
    45             android:id="@+id/text"/>
    46     </LinearLayout>
    47 
    48 
    49 </LinearLayout>

    5)最后是MainActivity,注意广播注销,否则造成内存泄漏!

      1 package com.example.nanchen.maweinaitest;
      2 
      3 import android.content.Context;
      4 import android.content.IntentFilter;
      5 import android.media.AudioManager;
      6 import android.net.wifi.WifiManager;
      7 import android.os.Bundle;
      8 import android.view.View;
      9 import android.view.View.OnClickListener;
     10 import android.widget.CompoundButton;
     11 import android.widget.CompoundButton.OnCheckedChangeListener;
     12 import android.widget.SeekBar;
     13 import android.widget.SeekBar.OnSeekBarChangeListener;
     14 import android.widget.Switch;
     15 import android.widget.TextView;
     16 import android.widget.Toast;
     17 
     18 import com.example.nanchen.maweinaitest.MyStatusReceiver.StatusCallback;
     19 
     20 import static android.content.Intent.ACTION_BATTERY_CHANGED;
     21 
     22 
     23 public class MainActivity extends ActivityBase implements StatusCallback {
     24 
     25     public static StatusCallback callback;
     26 
     27     private static final String TAG = "MainActivity";
     28     private Switch mSwitchWifi;
     29     private SeekBar mSeekBar;
     30     private WifiManager mWifiManager;
     31     private AudioManager mAudioManager;
     32     private TextView mTextView;
     33     private MyStatusReceiver mMyStatusReceiver;
     34 
     35     @Override
     36     protected void onCreate(Bundle savedInstanceState) {
     37         super.onCreate(savedInstanceState);
     38         setContentView(R.layout.activity_main);
     39         callback = this;
     40 
     41         bindView();
     42 
     43         initManager();
     44 
     45         bindListener();
     46 
     47     }
     48 
     49     private void initManager() {
     50         // 获取Wifi管理器
     51         mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
     52         // 把动态获取的信息放在onResume设置  避免按home键后再把APP切换到前台获取不到正常的数据
     53 
     54 
     55         // 获取音频管理器
     56         mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
     57     }
     58 
     59     /**
     60      * 绑定监听
     61      */
     62     private void bindListener() {
     63         // 为wifi开关事件设置监听
     64         mSwitchWifi.setOnCheckedChangeListener(new OnCheckedChangeListener() {
     65             @Override
     66             public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
     67                 if (!isChecked) {
     68                     buttonView.setChecked(false);
     69                     mWifiManager.setWifiEnabled(false);
     70                     Toast.makeText(MainActivity.this, "wifi关闭成功!", Toast.LENGTH_SHORT).show();
     71                 } else {
     72                     buttonView.setChecked(true);
     73                     mWifiManager.setWifiEnabled(true);
     74                     Toast.makeText(MainActivity.this, "wifi开启成功!", Toast.LENGTH_SHORT).show();
     75                 }
     76             }
     77         });
     78 
     79         // 再动态监听SeekBar
     80         mSeekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
     81             @Override
     82             public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
     83                 // 停止滑动
     84                 mSeekBar.setProgress(progress);
     85                 // 三个参数一次是  模式,值,标志位
     86                 mAudioManager.setStreamVolume(AudioManager.STREAM_SYSTEM, progress, 0);
     87             }
     88 
     89             @Override
     90             public void onStartTrackingTouch(SeekBar seekBar) {
     91 
     92             }
     93 
     94             @Override
     95             public void onStopTrackingTouch(SeekBar seekBar) {
     96 
     97             }
     98         });
     99 
    100         // 注册广播,添加三个Action
    101         IntentFilter intentFilter = new IntentFilter();
    102         intentFilter.addAction(ACTION_BATTERY_CHANGED);
    103         intentFilter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
    104         intentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
    105         mMyStatusReceiver = new MyStatusReceiver();
    106         registerReceiver(mMyStatusReceiver, intentFilter); // 注册监听广播
    107     }
    108 
    109 
    110     private int max;
    111     private int current;
    112 
    113     /**
    114      * 设置wifi开关
    115      */
    116     private void setWifiSwitch() {
    117         if (mWifiManager.isWifiEnabled()) {
    118             mSwitchWifi.setChecked(true);
    119         } else {
    120             mSwitchWifi.setChecked(false);
    121         }
    122     }
    123 
    124     @Override
    125     protected void onResume() {
    126         super.onResume();
    127         // 先动态设置wifi
    128         setWifiSwitch();
    129 
    130         // 再动态设置音频音量  参数为音量模式
    131         max = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_SYSTEM); // 最大音量
    132         current = mAudioManager.getStreamVolume(AudioManager.STREAM_SYSTEM); // 当前音量
    133 
    134         mSeekBar.setMax(max);// 设置seekBar
    135         mSeekBar.setProgress(current);
    136     }
    137 
    138     @Override
    139     protected void onPause() {
    140         super.onPause();
    141         // 一定记得注销广播,否则会造成内存泄漏
    142         unregisterReceiver(mMyStatusReceiver);
    143     }
    144 
    145     @SuppressWarnings("ConstantConditions")
    146     private void bindView() {
    147         mSwitchWifi = (Switch) findViewById(R.id.wifi);
    148         mSeekBar = (SeekBar) findViewById(R.id.seekBar);
    149         mTextView = (TextView) findViewById(R.id.text);
    150         findViewById(R.id.btn).setOnClickListener(new OnClickListener() {
    151             @Override
    152             public void onClick(View v) {
    153                 // 在这里获取当前电量信息
    154 
    155                 // 这里就不写了,实际上监听系统广播,它会自动实时获取电量信息
    156             }
    157         });
    158     }
    159 
    160 
    161     @Override
    162     public void onPowerChanged(String status) {
    163         mTextView.setText(status);
    164     }
    165 
    166     @Override
    167     public void onAudioChanged(final int status) {
    168         mSeekBar.setProgress(status);
    169     }
    170 
    171     @Override
    172     public void onWifiChanged(boolean status) {
    173         mSwitchWifi.setChecked(status);
    174     }
    175 
    176 }

    大概运行图如下:

     

    代码已上传至github:https://github.com/nanchen2251/ReceiverDemo

    转载于:https://www.cnblogs.com/liushilin/p/6037466.html

    展开全文
  • 一个简单的测试项目 该项目旨在允许使用quarkus开发人员版本进行容器化版本测试。 为什么? 如果在本地构建quarkus,则最终在本地maven存储库中将quarkus作为版本999-SNAPSHOT。然后,您可以将此版本的quarkus与测试...
  • 对于安卓用户来说,手机应用更新是很频繁的,我们能在每次升级版本的时候,都用户再去应用市场上重新下载遍,这样是很友好的。因此,在app里实现自动更新的功能,就显得很有必要了。 今天,就来聊一下,...

    对于安卓用户来说,手机应用更新是很频繁的,我们不能在每一次升级版本的时候,都让用户再去应用市场上重新下载一遍,这样是很不友好的。因此,在app里实现自动更新的功能,就显得很有必要了。
    今天,就来聊一下,如何使用蒲公英第三方平台和DownLoadManager来实现app自动更新的功能。从以下三个方面来说明:**

    1. app自动更新流程阐述

    2. 如何集成第三方平台(蒲公英)

    3. 如何使用系统自带类DownloadManager来实现下载

      一.app自动更新的流程:

      这里写图片描述

    二.如何集成第三方平台(蒲公英)

    1.如何创建蒲公英的账号和应用,大家自行去蒲公英的官网操作,在这里就不过多说明。

    2.导入依赖

    compile 'com.pgyersdk:sdk:2.5.6'

    3.添加权限:在AndroidManifest.xml中添加

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- 获取网络状态 -->
    <uses-permission android:name="android.permission.INTERNET" /> <!-- 网络通信 -->
    <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <!-- 获取设备信息 -->
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <!-- 获取MAC地址 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- 读写sdcard,storage等等 -->
    <uses-permission android:name="android.permission.RECORD_AUDIO" /> <!-- 允许程序录制音频 -->

    4.在AndroidManifest.xml中添加蒲公英提供的App key

    <meta-data
               android:name="PGYER_APPID"
               android:value="蒲公英key" > 
    </meta-data>

    5.在蒲公英上传你开发的app,获取你的蒲公英app key,将AndroidManifest.xml中的value值换成自己的蒲公英key
    这里写图片描述

    三.如何使用系统自带类DownloadManager来实现下载

    1.DownloadManager简单介绍
    DownloadManager是系统开放给第三方应用使用的类,包含两个静态内部类DownloadManager.Query和DownloadManager.Request。DownloadManager.Request用来请求一个下载,DownloadManager.Query用来查询下载信息。
    2.新建ApkDownloadReceiver广播类来监听DownloadManager下载任务的状态,通过downloadId来查找下载的任务,如果下载完成,就去安装apk,如果下载失败,则弹出吐司提示。

    public class ApkDownloadReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent data) {
            //获取下载任务的downloadId
            long downloadId = data.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
            if (downloadId == PrefUtils.getApkDownloadId()) {
                DownloadManager downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
                //通过downloadId来查找下载的任务
                Cursor query = downloadManager.query(new DownloadManager.Query().setFilterById(downloadId));
                try {
                    if (query.moveToFirst()) {
                        //获取下载任务的状态
                        int status = query.getInt(query.getColumnIndex(DownloadManager.COLUMN_STATUS));
                        switch (status) {
                            //下载暂停
                            case DownloadManager.STATUS_PAUSED:
                                break;
                            //下载延迟
                            case DownloadManager.STATUS_PENDING:
                                break;
                            //正在下载
                            case DownloadManager.STATUS_RUNNING:
                                break;
                            //下载完成
                            case DownloadManager.STATUS_SUCCESSFUL:
                                //下载完成安装APK
                                installApk(context,query);
                                break;
                            //下载失败
                            case DownloadManager.STATUS_FAILED:
                                //弹出提示
                                Toast.makeText(context, "下载失败", Toast.LENGTH_SHORT).show();
                                break;
                        }
    
                    }
                } finally {
                    query.close();
                }
            }
        }
    
        private void installApk(Context context,Cursor query) {
            String apkPath = query.getString(query.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME));
            Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE, Uri.fromFile(new File(apkPath)));
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(intent);
        }
    }

    3.在AndroidManifest.xml监听下载广播完成的动作

     <!--下载Apk-->
        <receiver android:name="com.example.marvinma.pgyerupdatedemo.ApkDownloadReceiver">
            <intent-filter>
                <action android:name="android.intent.action.DOWNLOAD_COMPLETE" />
            </intent-filter>
        </receiver>

    4.在MainActivity onStart方法中去注册蒲公英,在onDestroy方法中去反注册。

    @Override
        protected void onStart() {
            super.onStart();
            //获取DownloadManagerDownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
            if (PrefUtils.getApkDownloadId() != -1) {
                //通过保存的downloadId来获取索引
                Cursor query = downloadManager.query(new DownloadManager.Query().
                        setFilterById(PrefUtils.getApkDownloadId()));
                try {
                    if (query.moveToFirst()) {
                        //获取下载任务的状态
                        int status = query.getInt(query.getColumnIndex(DownloadManager.COLUMN_STATUS));
                        //如果已经在下载中,就返回,不再去下载
                        if (status == DownloadManager.STATUS_RUNNING) {
                            return;
                        } else {
                            //如果是其他状态,就将之前的下载记录移除
                            downloadManager.remove(query.getInt(query.getColumnIndex(DownloadManager.COLUMN_ID)));
                            PrefUtils.setApkDownloadId(-1);
                        }
                    }
                } finally {
                    query.close();
                }
            }
            //蒲公英注册
            PgyUpdateManager.register(this,null,new UpdateManagerListener() {
                        @Override
                        public void onNoUpdateAvailable() {}
                        @Override
                        public void onUpdateAvailable(String s) {
                            final AppBean appBean = getAppBeanFromString(s);
                            VersionUtils.showUpdateDialog(MainActivity.this,appBean);
                        }
                    }
    
            );
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            //蒲公英反注册
            PgyUpdateManager.unregister();
        }

    5.下载的提示框

    public class VersionUtils {
    
    
        public static void showUpdateDialog(final Context context, final AppBean appBean) {
            new AlertDialog.Builder(context)
                    .setTitle("发现新版本" + appBean.getVersionName())
                    .setMessage(appBean.getReleaseNote())
                    .setNegativeButton("暂时忽略", null)
                    .setPositiveButton("立即更新", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            DownloadManager downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
                            //将下载请求加入下载队列,加入下载队列后会给该任务返回一个long型的id,通过该id可以取消任务,重启任务、获取下载的文件
                            long apkDownloadId = downloadManager.enqueue(new DownloadManager.Request(Uri.parse(appBean.getDownloadURL()))
                                    .setVisibleInDownloadsUi(false));
                            Log.e("apkUrl",appBean.getDownloadURL());
                            //保存下载的id
                            PrefUtils.setApkDownloadId(apkDownloadId);
                        }
                    })
                    .show();
    
        }
    }
    

    至此,使用DownloadMananger来实现下载的逻辑就完成了。接着,我们修改build.gradle的versionCode和versionName,在蒲公英上传新的app

    android {
        compileSdkVersion 25
        buildToolsVersion "25.0.2"
        defaultConfig {
            applicationId "com.example.marvinma.pgyerupdatedemo"
            minSdkVersion 18
            targetSdkVersion 25
            versionCode 2
            versionName "2.0"
            testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        }
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
        }
    }

    这里写图片描述

    效果图:

    这里写图片描述

    完整代码地址:http://download.csdn.net/download/maguifen2012/10156755

    展开全文
  • 最近开发app,做了一个闹钟通知,到时间时,用notificaton在手机顶部弹出一 个通知(只能通过点击通知或上划通知取消),并发出铃声。因为通知设置了 setAutoCancel以点击通知后,通知是会自动消失的(状态栏和...
  • 下面带大家来一起写一个APP更新的功能.  其实这个功能很简单,,,,就是一个文件上传下载的功能 文件的地址就是放在你们服务器上面的路径,你请求后台的版本号和本地的版本号进行对比,如果比服务器上的低就调用...
  • 记得看文章三部曲,点赞,评论,转发。 微信搜索【程序员小安】关注还在移动开发领域...一个眼睛更大更亮,超级可爱的小姐姐,站在我面前,竟然比昨天的面试官更蠢萌,今天看天才少年如何把她带回家,什么鬼,是把off.
  • 我们还要知道热修复的原理,这样不管框架如何变化,只要基本原理不变,我们都可以快速掌握它,或者自己动手写一个适合项目的热修复框架。 第一轮技术面 两个面试官,针对简历上项目和内存及优化等方面问了很多,还有...
  • 今天苹果正式推送iOS14正式版的系统更新,不知你们更新了没有,这次的更新算是一个大版本的更新,同时也增加了许多的新功能有些功能,可能没有那么容易发现,苹果也没有极力的宣传,但是功能是真的好用,下面就分享...
  • 本系列将完整著述:如何快速从0开发一个完整的Flutter APP,配套高完成度Flutter开源项目和,同时会提供一些Flutter的开发细节技巧,之后深入二进制和实战为你全面解析Flutter。 GSY新书: 上架啦://电子版和 这个...
  • 【天极软件频道消息】存储空间不够是很多iOS用户遇到的问题,苹果在2015全球开发者大会(WWDC 2015)上简要介绍了一个关于节省iOS存储空间的解决方案——App Thinning,这项功能可以iOS设备在很多安装应用、更新...
  • 每一年都有批APP死亡消失,有的本就默默无闻,消失了连个水花都响,有的也许曾经业界知名甚至...没有用户,没有转化,那这个APP迟早要完。 那么,如何提高APP的转化率就成为各位的要解决的问题。 首先我们从用户...
  • uni-app一个使用 Vue.js 开发小程序、H5、App的统一前端框架。官网地址:https://uniapp.dcloud.io 开发者使用 Vue 语法编写代码,uni-app 框架将其编译到 小程序(微信/支付宝/百度/字节跳动/QQ/钉钉)、App...
  • uni-app一个使用 Vue.js 开发小程序、H5、App的统一前端框架。官网地址:https://uniapp.dcloud.io 开发者使用 Vue 语法编写代码,uni-app 框架将其编译到 小程序(微信/支付宝/百度/字节跳动/QQ/钉钉)、App...
  • 除了Bug,最你头疼的问题是什么?单身?秃头?996?面试造火箭,工作拧螺丝? 作为安卓开发者,除了Bug,经常会碰到下面这些问题: 应用卡顿,丢帧,屏幕画面撕裂,操作界面刷新缓慢,UI美观,布局混乱…这些...
  • 对于熟悉这个功能的小伙伴而言,它只藏在手机角落的一个小透明而已。快捷指令的由来事实上,「快捷指令」的前身是一款叫做「Workflow」的第三方效率工具。由于成绩一直突出,曾在2015年被评为“App Store最佳应用...
  • 在我改一个声音播放和录音的APP时,想APP使用Timer计时器自动每录5秒存储一次。 所以需要使用Timer计时器来完成。 但是我希望在使用该APP时能在APP界面内提示当前是第几次录音。 刚开始使用Toast.makeText();...
  •   最近这一年来,明显的感觉到自己获取新技术,新知识的入口不再那么有效了...一直在思索如何才能实现突破,最近终于有了点眉目,准备开通一个专栏,专门研究国内外知名app,学习,研究这些app使用的成熟的技术,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 676
精华内容 270
关键字:

如何让一个app不更新